mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
1) updated ipc.c NetUserGetInfo - load \\%L\%U instead of \\%L\HOMES
because the share must be browseable by a w95 client 2) send_mailslot_reply - unique or group datagram argument added. 3) netlogon.c - rewrote response packet to do the right thing for w95. 4) server.c reply_nt1() - added OEMDomainstring to the end. 5) (deep breath) reworked the nmbd-browsing code a little bit. i discovered two months ago that becoming a primary domain controller (and domain master browser) is done independently of becoming a backup domain controller (logon server) is done independently of becoming a local master browser. therefore, three sets of state-machines (instead of just one) are in place - each of which is responsible for taking samba through the required stages to become: a logon server; a domain master browser; and a local master browser. each of these three things can occur independently on each interface, _including_ the wins pseudo-interface. the only slight caveat is that the wins pseudo-interface, by virtue of _not_ being a broadcast interface, does _not_ register as a local master browser with the wins server, as this doesn't make sense. lkcl
This commit is contained in:
parent
ebaff730c9
commit
88c6a00c3c
@ -73,7 +73,8 @@
|
|||||||
/* server type identifiers */
|
/* server type identifiers */
|
||||||
#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
|
#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
|
||||||
#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
|
#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
|
||||||
#define AM_DOMCTL(work) (work->ServerType & SV_TYPE_DOMAIN_CTRL)
|
#define AM_DOMMST(work) (work->ServerType & SV_TYPE_DOMAIN_MASTER)
|
||||||
|
#define AM_DOMMEM(work) (work->ServerType & SV_TYPE_DOMAIN_MEMBER)
|
||||||
|
|
||||||
/* microsoft browser NetBIOS name */
|
/* microsoft browser NetBIOS name */
|
||||||
#define MSBROWSE "\001\002__MSBROWSE__\002"
|
#define MSBROWSE "\001\002__MSBROWSE__\002"
|
||||||
@ -85,16 +86,27 @@
|
|||||||
enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
|
enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
|
||||||
enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
|
enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
|
||||||
enum packet_type {NMB_PACKET, DGRAM_PACKET};
|
enum packet_type {NMB_PACKET, DGRAM_PACKET};
|
||||||
|
|
||||||
enum master_state
|
enum master_state
|
||||||
{
|
{
|
||||||
MST_NONE,
|
MST_POTENTIAL,
|
||||||
MST_WON,
|
MST_BACK,
|
||||||
MST_MSB,
|
MST_MSB,
|
||||||
MST_BROWSER,
|
MST_BROWSER
|
||||||
MST_DOMAIN_NONE,
|
};
|
||||||
MST_DOMAIN_MEM,
|
|
||||||
MST_DOMAIN_TST,
|
enum domain_state
|
||||||
MST_DOMAIN
|
{
|
||||||
|
DOMAIN_NONE,
|
||||||
|
DOMAIN_WAIT,
|
||||||
|
DOMAIN_MST
|
||||||
|
};
|
||||||
|
|
||||||
|
enum logon_state
|
||||||
|
{
|
||||||
|
LOGON_NONE,
|
||||||
|
LOGON_WAIT,
|
||||||
|
LOGON_SRV
|
||||||
};
|
};
|
||||||
|
|
||||||
enum state_type
|
enum state_type
|
||||||
@ -179,8 +191,14 @@ struct work_record
|
|||||||
|
|
||||||
struct server_record *serverlist;
|
struct server_record *serverlist;
|
||||||
|
|
||||||
/* stage of development from non-master to master browser / domain master */
|
/* stage of development from non-local-master up to local-master browser */
|
||||||
enum master_state state;
|
enum master_state mst_state;
|
||||||
|
|
||||||
|
/* stage of development from non-domain-master to domain master browser */
|
||||||
|
enum domain_state dom_state;
|
||||||
|
|
||||||
|
/* stage of development from non-logon-server to logon server */
|
||||||
|
enum logon_state log_state;
|
||||||
|
|
||||||
/* work group info */
|
/* work group info */
|
||||||
fstring work_group;
|
fstring work_group;
|
||||||
@ -367,6 +385,9 @@ struct packet_struct
|
|||||||
|
|
||||||
/* broadcast packet announcement intervals, in minutes */
|
/* broadcast packet announcement intervals, in minutes */
|
||||||
|
|
||||||
|
/* attempt to add domain logon and domain master names */
|
||||||
|
#define CHECK_TIME_ADD_DOM_NAMES 5
|
||||||
|
|
||||||
/* search for master browsers of workgroups samba knows about,
|
/* search for master browsers of workgroups samba knows about,
|
||||||
except default */
|
except default */
|
||||||
#define CHECK_TIME_MST_BROWSE 5
|
#define CHECK_TIME_MST_BROWSE 5
|
||||||
|
@ -411,8 +411,14 @@ void send_election(struct subnet_record *d, char *group,uint32 criterion,
|
|||||||
void name_unregister_work(struct subnet_record *d, char *name, int name_type);
|
void name_unregister_work(struct subnet_record *d, char *name, int name_type);
|
||||||
void name_register_work(struct subnet_record *d, char *name, int name_type,
|
void name_register_work(struct subnet_record *d, char *name, int name_type,
|
||||||
int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast);
|
int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast);
|
||||||
void become_master(struct subnet_record *d, struct work_record *work);
|
void become_local_master(struct subnet_record *d, struct work_record *work);
|
||||||
void become_nonmaster(struct subnet_record *d, struct work_record *work,
|
void become_domain_master(struct subnet_record *d, struct work_record *work);
|
||||||
|
void become_logon_server(struct subnet_record *d, struct work_record *work);
|
||||||
|
void unbecome_local_master(struct subnet_record *d, struct work_record *work,
|
||||||
|
int remove_type);
|
||||||
|
void unbecome_domain_master(struct subnet_record *d, struct work_record *work,
|
||||||
|
int remove_type);
|
||||||
|
void unbecome_logon_server(struct subnet_record *d, struct work_record *work,
|
||||||
int remove_type);
|
int remove_type);
|
||||||
void run_elections(time_t t);
|
void run_elections(time_t t);
|
||||||
void process_election(struct packet_struct *p,char *buf);
|
void process_election(struct packet_struct *p,char *buf);
|
||||||
@ -436,7 +442,8 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
|
|||||||
void queue_packet(struct packet_struct *packet);
|
void queue_packet(struct packet_struct *packet);
|
||||||
void run_packet_queue();
|
void run_packet_queue();
|
||||||
void listen_for_packets(BOOL run_election);
|
void listen_for_packets(BOOL run_election);
|
||||||
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
|
BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,
|
||||||
|
char *buf,int len,char *srcname,
|
||||||
char *dstname,int src_type,int dest_type,
|
char *dstname,int src_type,int dest_type,
|
||||||
struct in_addr dest_ip,struct in_addr src_ip);
|
struct in_addr dest_ip,struct in_addr src_ip);
|
||||||
|
|
||||||
@ -469,6 +476,7 @@ struct response_record *queue_netbios_packet(struct subnet_record *d,
|
|||||||
|
|
||||||
void remove_name_entry(struct subnet_record *d, char *name,int type);
|
void remove_name_entry(struct subnet_record *d, char *name,int type);
|
||||||
void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags);
|
void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags);
|
||||||
|
void add_domain_names(time_t t);
|
||||||
void add_my_names(void);
|
void add_my_names(void);
|
||||||
void remove_my_names();
|
void remove_my_names();
|
||||||
void refresh_my_names(time_t t);
|
void refresh_my_names(time_t t);
|
||||||
|
@ -797,6 +797,21 @@ char *Strstr(char *s, char *p);
|
|||||||
/* what server type are we currently */
|
/* what server type are we currently */
|
||||||
|
|
||||||
|
|
||||||
|
/* Capabilities. see ftp.microsoft.com/developr/drg/cifs/cifs/cifs4.txt */
|
||||||
|
|
||||||
|
#define CAP_RAW_MODE 0x0001
|
||||||
|
#define CAP_MPX_MODE 0x0002
|
||||||
|
#define CAP_UNICODE 0x0004
|
||||||
|
#define CAP_LARGE_FILES 0x0008
|
||||||
|
#define CAP_NT_SMBS 0x0010
|
||||||
|
#define CAP_RPC_REMOTE_APIS 0x0020
|
||||||
|
#define CAP_STATUS32 0x0040
|
||||||
|
#define CAP_LEVEL_II_OPLOCKS 0x0080
|
||||||
|
#define CAP_LOCK_AND_READ 0x0100
|
||||||
|
#define CAP_NT_FIND 0x0200
|
||||||
|
#define CAP_DFS 0x1000
|
||||||
|
#define CAP_LARGE_READX 0x4000
|
||||||
|
|
||||||
/* protocol types. It assumes that higher protocols include lower protocols
|
/* protocol types. It assumes that higher protocols include lower protocols
|
||||||
as subsets */
|
as subsets */
|
||||||
enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANMAN1,PROTOCOL_LANMAN2,PROTOCOL_NT1};
|
enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANMAN1,PROTOCOL_LANMAN2,PROTOCOL_NT1};
|
||||||
|
@ -79,7 +79,8 @@ void announce_request(struct work_record *work, struct in_addr ip)
|
|||||||
of 0x1e, then we could get the master browser to announce to
|
of 0x1e, then we could get the master browser to announce to
|
||||||
us instead of the members of the workgroup. wha-hey! */
|
us instead of the members of the workgroup. wha-hey! */
|
||||||
|
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
send_mailslot_reply(False, BROWSE_MAILSLOT,ClientDGRAM,
|
||||||
|
outbuf,PTR_DIFF(p,outbuf),
|
||||||
myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip));
|
myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +107,8 @@ void do_announce_request(char *info, char *to_name, int announce_type,
|
|||||||
strupper(p);
|
strupper(p);
|
||||||
p = skip_string(p,1);
|
p = skip_string(p,1);
|
||||||
|
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
|
||||||
|
outbuf,PTR_DIFF(p,outbuf),
|
||||||
myname,to_name,from,to,dest_ip,*iface_ip(dest_ip));
|
myname,to_name,from,to,dest_ip,*iface_ip(dest_ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +174,7 @@ void do_announce_host(int command,
|
|||||||
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
|
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
|
||||||
|
|
||||||
/* send the announcement */
|
/* send the announcement */
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
|
send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,outbuf,
|
||||||
PTR_DIFF(p,outbuf),
|
PTR_DIFF(p,outbuf),
|
||||||
from_name, to_name,
|
from_name, to_name,
|
||||||
from_type, to_type,
|
from_type, to_type,
|
||||||
|
@ -91,7 +91,9 @@ static struct work_record *make_workgroup(char *name)
|
|||||||
work->ElectionCount = 0;
|
work->ElectionCount = 0;
|
||||||
work->needelection = False;
|
work->needelection = False;
|
||||||
work->needannounce = True;
|
work->needannounce = True;
|
||||||
work->state = MST_NONE;
|
work->mst_state = MST_POTENTIAL;
|
||||||
|
work->dom_state = DOMAIN_NONE;
|
||||||
|
work->log_state = LOGON_NONE;
|
||||||
|
|
||||||
/* make sure all token representations of workgroups are unique */
|
/* make sure all token representations of workgroups are unique */
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ extern struct subnet_record *subnetlist;
|
|||||||
|
|
||||||
extern uint16 nb_type; /* samba's NetBIOS name type */
|
extern uint16 nb_type; /* samba's NetBIOS name type */
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
occasionally check to see if the master browser is around
|
occasionally check to see if the master browser is around
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
@ -167,7 +168,8 @@ void send_election(struct subnet_record *d, char *group,uint32 criterion,
|
|||||||
strupper(p);
|
strupper(p);
|
||||||
p = skip_string(p,1);
|
p = skip_string(p,1);
|
||||||
|
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
|
||||||
|
outbuf,PTR_DIFF(p,outbuf),
|
||||||
name,group,0,0x1e,d->bcast_ip,*iface_ip(d->bcast_ip));
|
name,group,0,0x1e,d->bcast_ip,*iface_ip(d->bcast_ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,26 +185,39 @@ void send_election(struct subnet_record *d, char *group,uint32 criterion,
|
|||||||
void name_unregister_work(struct subnet_record *d, char *name, int name_type)
|
void name_unregister_work(struct subnet_record *d, char *name, int name_type)
|
||||||
{
|
{
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
|
int remove_type_local = 0;
|
||||||
|
int remove_type_domain = 0;
|
||||||
|
int remove_type_logon = 0;
|
||||||
|
|
||||||
remove_netbios_name(d,name,name_type,SELF,ipzero);
|
remove_netbios_name(d,name,name_type,SELF,ipzero);
|
||||||
|
|
||||||
if (!(work = find_workgroupstruct(d, name, False))) return;
|
if (!(work = find_workgroupstruct(d, name, False))) return;
|
||||||
|
|
||||||
if (ms_browser_name(name, name_type) ||
|
/* work out what to unbecome, from the name type being removed */
|
||||||
(AM_MASTER(work) && strequal(name, lp_workgroup()) == 0 &&
|
|
||||||
(name_type == 0x1d || name_type == 0x1b)))
|
|
||||||
{
|
|
||||||
int remove_type = 0;
|
|
||||||
|
|
||||||
if (ms_browser_name(name, name_type))
|
if (ms_browser_name(name, name_type))
|
||||||
remove_type = SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER;
|
{
|
||||||
if (name_type == 0x1d)
|
remove_type_local |= SV_TYPE_MASTER_BROWSER;
|
||||||
remove_type = SV_TYPE_MASTER_BROWSER;
|
|
||||||
if (name_type == 0x1b)
|
|
||||||
remove_type = SV_TYPE_DOMAIN_MASTER;
|
|
||||||
|
|
||||||
become_nonmaster(d, work, remove_type);
|
|
||||||
}
|
}
|
||||||
|
if (AM_MASTER(work) && strequal(name, lp_workgroup()) == 0 &&
|
||||||
|
name_type == 0x1d)
|
||||||
|
{
|
||||||
|
remove_type_local |= SV_TYPE_MASTER_BROWSER;
|
||||||
|
}
|
||||||
|
if (AM_DOMMST(work) && strequal(name, lp_workgroup()) == 0 &&
|
||||||
|
name_type == 0x1b)
|
||||||
|
{
|
||||||
|
remove_type_domain |= SV_TYPE_DOMAIN_MASTER;
|
||||||
|
}
|
||||||
|
if (AM_DOMMEM(work) && strequal(name, lp_workgroup()) == 0 &&
|
||||||
|
name_type == 0x1c)
|
||||||
|
{
|
||||||
|
remove_type_logon|= SV_TYPE_DOMAIN_MEMBER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove_type_local ) unbecome_local_master (d, work, remove_type_local );
|
||||||
|
if (remove_type_domain) unbecome_domain_master(d, work, remove_type_domain);
|
||||||
|
if (remove_type_logon ) unbecome_logon_server (d, work, remove_type_logon );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -227,12 +242,28 @@ void name_register_work(struct subnet_record *d, char *name, int name_type,
|
|||||||
|
|
||||||
if (work)
|
if (work)
|
||||||
{
|
{
|
||||||
if (work->state != MST_NONE)
|
if (work->mst_state != MST_POTENTIAL)
|
||||||
{
|
{
|
||||||
/* samba is in the process of working towards master browser-ness.
|
/* samba is working towards local master browser-ness.
|
||||||
initiate the next stage.
|
initiate the next stage.
|
||||||
*/
|
*/
|
||||||
become_master(d, work);
|
become_local_master(d, work);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (work->dom_state != DOMAIN_NONE)
|
||||||
|
{
|
||||||
|
/* samba is working towards domain master browser-ness.
|
||||||
|
initiate the next stage.
|
||||||
|
*/
|
||||||
|
become_domain_master(d, work);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (work->log_state != LOGON_NONE)
|
||||||
|
{
|
||||||
|
/* samba is working towards domain master browser-ness.
|
||||||
|
initiate the next stage.
|
||||||
|
*/
|
||||||
|
become_logon_server(d, work);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,29 +272,28 @@ void name_register_work(struct subnet_record *d, char *name, int name_type,
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
become the master browser.
|
become the local master browser.
|
||||||
|
|
||||||
this is done in stages. note that this could take a while,
|
this is done in stages. note that this could take a while,
|
||||||
particularly on a broadcast subnet, as we have to wait for
|
particularly on a broadcast subnet, as we have to wait for
|
||||||
the implicit registration of each name to be accepted.
|
the implicit registration of each name to be accepted.
|
||||||
|
|
||||||
as each name is successfully registered, become_master() is
|
as each name is successfully registered, become_local_master() is
|
||||||
called again, in order to initiate the next stage. see
|
called again, in order to initiate the next stage. see
|
||||||
dead_netbios_entry() - deals with implicit name registration
|
dead_netbios_entry() - deals with implicit name registration
|
||||||
and response_name_reg() - deals with explicit registration
|
and response_name_reg() - deals with explicit registration
|
||||||
with a WINS server.
|
with a WINS server.
|
||||||
|
|
||||||
stage 1: was MST_NONE - go to MST_NONE and register ^1^2__MSBROWSE__^2^1.
|
stage 1: was MST_POTENTIAL - go to MST_POTENTIAL and register ^1^2__MSBROWSE__^2^1.
|
||||||
stage 2: was MST_WON - go to MST_MSB and register WORKGROUP(0x1d)
|
stage 2: was MST_BACK - go to MST_MSB and register WORKGROUP(0x1d)
|
||||||
stage 3: was MST_MSB - go to MST_BROWSER and register WORKGROUP(0x1b)
|
stage 3: was MST_MSB - go to MST_BROWSER and stay there
|
||||||
stage 4: was MST_BROWSER - go to MST_DOMAIN (do not pass GO, do not...)
|
|
||||||
|
|
||||||
XXXX note: this code still does not cope with the distinction
|
XXXX note: this code still does not cope with the distinction
|
||||||
between different types of nodes, particularly between M and P
|
between different types of nodes, particularly between M and P
|
||||||
nodes. that comes later.
|
nodes. that comes later.
|
||||||
|
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
void become_master(struct subnet_record *d, struct work_record *work)
|
void become_local_master(struct subnet_record *d, struct work_record *work)
|
||||||
{
|
{
|
||||||
/* domain type must be limited to domain enum + server type. it must
|
/* domain type must be limited to domain enum + server type. it must
|
||||||
not have SV_TYPE_SERVER or anything else with SERVER in it, else
|
not have SV_TYPE_SERVER or anything else with SERVER in it, else
|
||||||
@ -272,17 +302,17 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
*/
|
*/
|
||||||
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
|
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
|
||||||
|
|
||||||
if (!work) return;
|
if (!work || !d) return;
|
||||||
|
|
||||||
DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
|
DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
|
||||||
work->work_group,inet_ntoa(d->bcast_ip),work->state));
|
work->work_group,inet_ntoa(d->bcast_ip),work->mst_state));
|
||||||
|
|
||||||
switch (work->state)
|
switch (work->mst_state)
|
||||||
{
|
{
|
||||||
case MST_NONE: /* while we were nothing but a server... */
|
case MST_POTENTIAL: /* while we were nothing but a server... */
|
||||||
{
|
{
|
||||||
DEBUG(3,("go to first stage: register ^1^2__MSBROWSE__^2^1\n"));
|
DEBUG(3,("go to first stage: register ^1^2__MSBROWSE__^2^1\n"));
|
||||||
work->state = MST_WON; /* ... an election win was successful */
|
work->mst_state = MST_BACK; /* ... an election win was successful */
|
||||||
|
|
||||||
work->ElectionCriterion |= 0x5;
|
work->ElectionCriterion |= 0x5;
|
||||||
|
|
||||||
@ -294,12 +324,13 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
add_my_name_entry(d,MSBROWSE ,0x01,nb_type|NB_ACTIVE|NB_GROUP);
|
add_my_name_entry(d,MSBROWSE ,0x01,nb_type|NB_ACTIVE|NB_GROUP);
|
||||||
|
|
||||||
/* DON'T do anything else after calling add_my_name_entry() */
|
/* DON'T do anything else after calling add_my_name_entry() */
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
case MST_WON: /* while nothing had happened except we won an election... */
|
|
||||||
|
case MST_BACK: /* while nothing had happened except we won an election... */
|
||||||
{
|
{
|
||||||
DEBUG(3,("go to second stage: register as master browser\n"));
|
DEBUG(3,("go to second stage: register as master browser\n"));
|
||||||
work->state = MST_MSB; /* ... registering MSBROWSE was successful */
|
work->mst_state = MST_MSB; /* ... registering MSBROWSE was successful */
|
||||||
|
|
||||||
/* add server entry on successful registration of MSBROWSE */
|
/* add server entry on successful registration of MSBROWSE */
|
||||||
add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
|
add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
|
||||||
@ -308,12 +339,13 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE);
|
add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE);
|
||||||
|
|
||||||
/* DON'T do anything else after calling add_my_name_entry() */
|
/* DON'T do anything else after calling add_my_name_entry() */
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MST_MSB: /* while we were still only registered MSBROWSE state... */
|
case MST_MSB: /* while we were still only registered MSBROWSE state... */
|
||||||
{
|
{
|
||||||
DEBUG(3,("2nd stage complete: registered as master browser\n"));
|
DEBUG(3,("2nd stage complete: registered as master browser\n"));
|
||||||
work->state = MST_BROWSER; /* ... registering WORKGROUP(1d) succeeded */
|
work->mst_state = MST_BROWSER; /* ... registering WORKGROUP(1d) succeeded */
|
||||||
|
|
||||||
/* update our server status */
|
/* update our server status */
|
||||||
work->ServerType |= SV_TYPE_MASTER_BROWSER;
|
work->ServerType |= SV_TYPE_MASTER_BROWSER;
|
||||||
@ -322,114 +354,17 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
if (work->serverlist == NULL) /* no servers! */
|
if (work->serverlist == NULL) /* no servers! */
|
||||||
{
|
{
|
||||||
/* ask all servers on our local net to announce to us */
|
/* ask all servers on our local net to announce to us */
|
||||||
|
/* XXXX OOPS! add_server_entry will always add one entry - our own. */
|
||||||
announce_request(work, d->bcast_ip);
|
announce_request(work, d->bcast_ip);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MST_BROWSER:
|
case MST_BROWSER:
|
||||||
{
|
{
|
||||||
/* don't have to do anything: just report success */
|
/* don't have to do anything: just report success */
|
||||||
DEBUG(3,("3rd stage: become master browser!\n"));
|
DEBUG(3,("3rd stage: become master browser!\n"));
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MST_DOMAIN_NONE:
|
|
||||||
{
|
|
||||||
if (lp_domain_master())
|
|
||||||
{
|
|
||||||
work->state = MST_DOMAIN_MEM; /* ... become domain member */
|
|
||||||
DEBUG(3,("domain first stage: register as domain member\n"));
|
|
||||||
|
|
||||||
/* add domain member name */
|
|
||||||
add_my_name_entry(d,work->work_group,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
|
|
||||||
|
|
||||||
/* DON'T do anything else after calling add_my_name_entry() */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG(4,("samba not configured as a domain master.\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MST_DOMAIN_MEM:
|
|
||||||
{
|
|
||||||
if (lp_domain_master())
|
|
||||||
{
|
|
||||||
work->state = MST_DOMAIN_TST; /* ... possibly become domain master */
|
|
||||||
DEBUG(3,("domain second stage: register as domain master\n"));
|
|
||||||
|
|
||||||
if (lp_domain_logons())
|
|
||||||
{
|
|
||||||
work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
|
|
||||||
add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add domain master name */
|
|
||||||
add_my_name_entry(d,work->work_group,0x1b,nb_type|NB_ACTIVE );
|
|
||||||
|
|
||||||
/* DON'T do anything else after calling add_my_name_entry() */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG(4,("samba not configured as a domain master.\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MST_DOMAIN_TST: /* while we were still a master browser... */
|
|
||||||
{
|
|
||||||
/* update our server status */
|
|
||||||
if (lp_domain_master())
|
|
||||||
{
|
|
||||||
struct subnet_record *d1;
|
|
||||||
uint32 update_type = 0;
|
|
||||||
|
|
||||||
DEBUG(3,("domain third stage: samba is now a domain master.\n"));
|
|
||||||
work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
|
|
||||||
|
|
||||||
update_type |= DFLT_SERVER_TYPE | SV_TYPE_DOMAIN_MASTER |
|
|
||||||
SV_TYPE_POTENTIAL_BROWSER;
|
|
||||||
|
|
||||||
work->ServerType |= update_type;
|
|
||||||
add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
|
|
||||||
|
|
||||||
for (d1 = subnetlist; d1; d1 = d1->next)
|
|
||||||
{
|
|
||||||
struct work_record *w;
|
|
||||||
if (ip_equal(d1->bcast_ip, d->bcast_ip)) continue;
|
|
||||||
|
|
||||||
for (w = d1->workgrouplist; w; w = w->next)
|
|
||||||
{
|
|
||||||
struct server_record *s = find_server(w, myname);
|
|
||||||
if (strequal(w->work_group, work->work_group))
|
|
||||||
{
|
|
||||||
w->ServerType |= update_type;
|
|
||||||
}
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
s->serv.type |= update_type;
|
|
||||||
DEBUG(4,("found server %s on %s: update to %8x\n",
|
|
||||||
s->serv.name, inet_ntoa(d1->bcast_ip),
|
|
||||||
s->serv.type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MST_DOMAIN:
|
|
||||||
{
|
|
||||||
/* don't have to do anything: just report success */
|
|
||||||
DEBUG(3,("fifth stage: there isn't one yet!\n"));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -437,52 +372,250 @@ void become_master(struct subnet_record *d, struct work_record *work)
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
unbecome the master browser. initates removal of necessary netbios
|
become the domain master browser.
|
||||||
names, and tells the world that we are no longer a master browser.
|
|
||||||
|
this is done in stages. note that this could take a while,
|
||||||
|
particularly on a broadcast subnet, as we have to wait for
|
||||||
|
the implicit registration of each name to be accepted.
|
||||||
|
|
||||||
|
as each name is successfully registered, become_domain_master() is
|
||||||
|
called again, in order to initiate the next stage. see
|
||||||
|
dead_netbios_entry() - deals with implicit name registration
|
||||||
|
and response_name_reg() - deals with explicit registration
|
||||||
|
with a WINS server.
|
||||||
|
|
||||||
|
stage 1: was DOMAIN_NONE - go to DOMAIN_MST
|
||||||
|
|
||||||
|
XXXX note: this code still does not cope with the distinction
|
||||||
|
between different types of nodes, particularly between M and P
|
||||||
|
nodes. that comes later.
|
||||||
|
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
void become_nonmaster(struct subnet_record *d, struct work_record *work,
|
void become_domain_master(struct subnet_record *d, struct work_record *work)
|
||||||
|
{
|
||||||
|
/* domain type must be limited to domain enum + server type. it must
|
||||||
|
not have SV_TYPE_SERVER or anything else with SERVER in it, else
|
||||||
|
clients get confused and start thinking this entry is a server
|
||||||
|
not a workgroup
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!work || !d) return;
|
||||||
|
|
||||||
|
DEBUG(2,("Becoming domain master for %s %s (currently at stage %d)\n",
|
||||||
|
work->work_group,inet_ntoa(d->bcast_ip),work->dom_state));
|
||||||
|
|
||||||
|
switch (work->dom_state)
|
||||||
|
{
|
||||||
|
case DOMAIN_NONE: /* while we were nothing but a server... */
|
||||||
|
{
|
||||||
|
if (lp_domain_master())
|
||||||
|
{
|
||||||
|
DEBUG(3,("go to first stage: register <1b> name\n"));
|
||||||
|
work->dom_state = DOMAIN_WAIT;
|
||||||
|
|
||||||
|
/* XXXX the 0x1b is domain master browser name */
|
||||||
|
add_my_name_entry(d, lp_workgroup(),0x1b,nb_type|NB_ACTIVE|NB_GROUP);
|
||||||
|
|
||||||
|
/* DON'T do anything else after calling add_my_name_entry() */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG(4,("samba not configured as a domain master.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DOMAIN_WAIT:
|
||||||
|
{
|
||||||
|
if (lp_domain_master())
|
||||||
|
{
|
||||||
|
work->dom_state = DOMAIN_MST; /* ... become domain master */
|
||||||
|
DEBUG(3,("domain first stage: register as domain member\n"));
|
||||||
|
|
||||||
|
/* update our server status */
|
||||||
|
work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER;
|
||||||
|
add_server_entry(d,work,myname,work->ServerType,0,
|
||||||
|
lp_serverstring(),True);
|
||||||
|
|
||||||
|
DEBUG(4,("samba is now a domain master\n"));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG(4,("samba not configured as a domain master.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DOMAIN_MST:
|
||||||
|
{
|
||||||
|
/* don't have to do anything: just report success */
|
||||||
|
DEBUG(3,("domain second stage: there isn't one!\n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
become a logon server.
|
||||||
|
******************************************************************/
|
||||||
|
void become_logon_server(struct subnet_record *d, struct work_record *work)
|
||||||
|
{
|
||||||
|
if (!work || !d) return;
|
||||||
|
|
||||||
|
DEBUG(2,("Becoming logon server for %s %s (currently at stage %d)\n",
|
||||||
|
work->work_group,inet_ntoa(d->bcast_ip),work->log_state));
|
||||||
|
|
||||||
|
switch (work->log_state)
|
||||||
|
{
|
||||||
|
case LOGON_NONE: /* while we were nothing but a server... */
|
||||||
|
{
|
||||||
|
if (lp_domain_logons())
|
||||||
|
{
|
||||||
|
DEBUG(3,("go to first stage: register <1c> name\n"));
|
||||||
|
work->log_state = LOGON_WAIT;
|
||||||
|
|
||||||
|
/* XXXX the 0x1c is apparently something to do with domain logons */
|
||||||
|
add_my_name_entry(d, lp_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP);
|
||||||
|
|
||||||
|
/* DON'T do anything else after calling add_my_name_entry() */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
DEBUG(4,("samba not configured as a logon master.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LOGON_WAIT:
|
||||||
|
{
|
||||||
|
if (lp_domain_logons())
|
||||||
|
{
|
||||||
|
work->log_state = LOGON_SRV; /* ... become logon server */
|
||||||
|
DEBUG(3,("logon second stage: register \n"));
|
||||||
|
|
||||||
|
/* update our server status */
|
||||||
|
work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER;
|
||||||
|
add_server_entry(d,work,myname,work->ServerType,0,
|
||||||
|
lp_serverstring(),True);
|
||||||
|
|
||||||
|
/* DON'T do anything else after calling add_my_name_entry() */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG(4,("samba not configured as a logon server.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LOGON_SRV:
|
||||||
|
{
|
||||||
|
DEBUG(3,("logon third stage: there isn't one!\n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
unbecome the local master browser. initates removal of necessary netbios
|
||||||
|
names, and tells the world that we are no longer a master browser.
|
||||||
|
|
||||||
|
XXXX this _should_ be used to demote to a backup master browser, without
|
||||||
|
going straight to non-master browser. another time.
|
||||||
|
|
||||||
|
******************************************************************/
|
||||||
|
void unbecome_local_master(struct subnet_record *d, struct work_record *work,
|
||||||
int remove_type)
|
int remove_type)
|
||||||
{
|
{
|
||||||
int new_server_type = work->ServerType;
|
int new_server_type = work->ServerType;
|
||||||
|
|
||||||
DEBUG(2,("Becoming non-master for %s\n",work->work_group));
|
/* can only remove master types with this function */
|
||||||
|
remove_type &= SV_TYPE_MASTER_BROWSER;
|
||||||
/* can only remove master or domain types with this function */
|
|
||||||
remove_type &= SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER;
|
|
||||||
|
|
||||||
/* unbecome a master browser; unbecome a domain master, too :-( */
|
|
||||||
if (remove_type & SV_TYPE_MASTER_BROWSER)
|
|
||||||
remove_type |= SV_TYPE_DOMAIN_MASTER;
|
|
||||||
|
|
||||||
new_server_type &= ~remove_type;
|
new_server_type &= ~remove_type;
|
||||||
|
|
||||||
if (!(new_server_type & (SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER)))
|
if (remove_type)
|
||||||
{
|
{
|
||||||
|
DEBUG(2,("Becoming local non-master for %s\n",work->work_group));
|
||||||
|
|
||||||
/* no longer a master browser of any sort */
|
/* no longer a master browser of any sort */
|
||||||
|
|
||||||
work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
|
work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
|
||||||
work->ElectionCriterion &= ~0x4;
|
work->ElectionCriterion &= ~0x4;
|
||||||
work->state = MST_NONE;
|
work->mst_state = MST_POTENTIAL;
|
||||||
|
|
||||||
/* announce ourselves as no longer active as a master browser. */
|
/* announce ourselves as no longer active as a master browser. */
|
||||||
announce_server(d, work, work->work_group, myname, 0, 0);
|
announce_server(d, work, work->work_group, myname, 0, 0);
|
||||||
remove_name_entry(d,MSBROWSE ,0x01);
|
remove_name_entry(d,MSBROWSE ,0x01);
|
||||||
|
remove_name_entry(d,work->work_group,0x1d);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
work->ServerType = new_server_type;
|
|
||||||
|
|
||||||
if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
|
|
||||||
|
/*******************************************************************
|
||||||
|
unbecome the domain master browser. initates removal of necessary netbios
|
||||||
|
names, and tells the world that we are no longer a domain browser.
|
||||||
|
******************************************************************/
|
||||||
|
void unbecome_domain_master(struct subnet_record *d, struct work_record *work,
|
||||||
|
int remove_type)
|
||||||
|
{
|
||||||
|
int new_server_type = work->ServerType;
|
||||||
|
|
||||||
|
DEBUG(2,("Becoming domain non-master for %s\n",work->work_group));
|
||||||
|
|
||||||
|
/* can only remove master or domain types with this function */
|
||||||
|
remove_type &= SV_TYPE_DOMAIN_MASTER;
|
||||||
|
|
||||||
|
new_server_type &= ~remove_type;
|
||||||
|
|
||||||
|
if (remove_type)
|
||||||
{
|
{
|
||||||
if (work->state == MST_DOMAIN)
|
/* no longer a domain master browser of any sort */
|
||||||
work->state = MST_BROWSER;
|
|
||||||
|
work->dom_state = DOMAIN_NONE;
|
||||||
|
|
||||||
|
/* announce ourselves as no longer active as a master browser. */
|
||||||
|
announce_server(d, work, work->work_group, myname, 0, 0);
|
||||||
remove_name_entry(d,work->work_group,0x1b);
|
remove_name_entry(d,work->work_group,0x1b);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(work->ServerType & SV_TYPE_MASTER_BROWSER))
|
|
||||||
|
/*******************************************************************
|
||||||
|
unbecome the logon server. initates removal of necessary netbios
|
||||||
|
names, and tells the world that we are no longer a logon server.
|
||||||
|
******************************************************************/
|
||||||
|
void unbecome_logon_server(struct subnet_record *d, struct work_record *work,
|
||||||
|
int remove_type)
|
||||||
|
{
|
||||||
|
int new_server_type = work->ServerType;
|
||||||
|
|
||||||
|
DEBUG(2,("Becoming logon non-server for %s\n",work->work_group));
|
||||||
|
|
||||||
|
/* can only remove master or domain types with this function */
|
||||||
|
remove_type &= SV_TYPE_DOMAIN_MEMBER;
|
||||||
|
|
||||||
|
new_server_type &= ~remove_type;
|
||||||
|
|
||||||
|
if (remove_type)
|
||||||
{
|
{
|
||||||
if (work->state >= MST_BROWSER)
|
/* no longer a master browser of any sort */
|
||||||
work->state = MST_NONE;
|
|
||||||
remove_name_entry(d,work->work_group,0x1d);
|
work->log_state = LOGON_NONE;
|
||||||
|
|
||||||
|
/* announce ourselves as no longer active as a master browser. */
|
||||||
|
announce_server(d, work, work->work_group, myname, 0, 0);
|
||||||
|
remove_name_entry(d,work->work_group,0x1c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,9 +651,9 @@ void run_elections(time_t t)
|
|||||||
work->work_group,inet_ntoa(d->bcast_ip)));
|
work->work_group,inet_ntoa(d->bcast_ip)));
|
||||||
|
|
||||||
work->RunningElection = False;
|
work->RunningElection = False;
|
||||||
work->state = MST_NONE;
|
work->mst_state = MST_POTENTIAL;
|
||||||
|
|
||||||
become_master(d, work);
|
become_local_master(d, work);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -598,7 +731,7 @@ void process_election(struct packet_struct *p,char *buf)
|
|||||||
if (!work->RunningElection) {
|
if (!work->RunningElection) {
|
||||||
work->needelection = True;
|
work->needelection = True;
|
||||||
work->ElectionCount=0;
|
work->ElectionCount=0;
|
||||||
work->state = MST_NONE;
|
work->mst_state = MST_POTENTIAL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
work->needelection = False;
|
work->needelection = False;
|
||||||
@ -608,9 +741,7 @@ void process_election(struct packet_struct *p,char *buf)
|
|||||||
DEBUG(3,(">>> Lost election on %s %s <<<\n",
|
DEBUG(3,(">>> Lost election on %s %s <<<\n",
|
||||||
work->work_group,inet_ntoa(d->bcast_ip)));
|
work->work_group,inet_ntoa(d->bcast_ip)));
|
||||||
if (AM_MASTER(work))
|
if (AM_MASTER(work))
|
||||||
become_nonmaster(d, work,
|
unbecome_local_master(d, work, SV_TYPE_MASTER_BROWSER);
|
||||||
SV_TYPE_MASTER_BROWSER|
|
|
||||||
SV_TYPE_DOMAIN_MASTER);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,86 +54,101 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len)
|
|||||||
pstring outbuf;
|
pstring outbuf;
|
||||||
int code,reply_code;
|
int code,reply_code;
|
||||||
struct work_record *work;
|
struct work_record *work;
|
||||||
|
char unknown_byte = 0;
|
||||||
|
uint16 request_count = 0;
|
||||||
|
uint16 token = 0;
|
||||||
|
|
||||||
if (!d) return;
|
if (!d) return;
|
||||||
|
|
||||||
if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
|
if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False))) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (!lp_domain_logons()) {
|
if (!lp_domain_logons())
|
||||||
|
{
|
||||||
DEBUG(3,("No domain logons\n"));
|
DEBUG(3,("No domain logons\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = SVAL(buf,0);
|
code = SVAL(buf,0);
|
||||||
switch (code) {
|
switch (code)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
char *machine = buf+2;
|
char *machine = buf+2;
|
||||||
char *user = skip_string(machine,1);
|
char *user = skip_string(machine,1);
|
||||||
|
char *tmp;
|
||||||
logname = skip_string(user,1);
|
logname = skip_string(user,1);
|
||||||
reply_code = 6;
|
tmp = skip_string(logname,1);
|
||||||
|
unknown_byte = CVAL(tmp,0);
|
||||||
|
request_count = SVAL(tmp,1);
|
||||||
|
token = SVAL(tmp,3);
|
||||||
|
|
||||||
|
reply_code = 0x6;
|
||||||
strcpy(reply_name,myname);
|
strcpy(reply_name,myname);
|
||||||
strupper(reply_name);
|
strupper(reply_name);
|
||||||
add_slashes = True;
|
add_slashes = True;
|
||||||
DEBUG(3,("Domain login request from %s(%s) user=%s\n",
|
DEBUG(3,("Domain login request from %s(%s) user=%s token=%x\n",
|
||||||
machine,inet_ntoa(p->ip),user));
|
machine,inet_ntoa(p->ip),user,token));
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 7:
|
case 7:
|
||||||
{
|
{
|
||||||
char *machine = buf+2;
|
char *machine = buf+2;
|
||||||
logname = skip_string(machine,1);
|
logname = skip_string(machine,1);
|
||||||
reply_code = 7;
|
token = SVAL(skip_string(logname,1),0);
|
||||||
|
|
||||||
strcpy(reply_name,lp_domain_controller());
|
strcpy(reply_name,lp_domain_controller());
|
||||||
if (!*reply_name) {
|
if (!*reply_name)
|
||||||
|
{
|
||||||
|
/* oo! no domain controller. must be us, then */
|
||||||
strcpy(reply_name,myname);
|
strcpy(reply_name,myname);
|
||||||
reply_code = 0xC;
|
reply_code = 0xC;
|
||||||
}
|
}
|
||||||
strupper(reply_name);
|
else
|
||||||
DEBUG(3,("GETDC request from %s(%s), reporting %s 0x%2x\n",
|
{
|
||||||
machine,inet_ntoa(p->ip), reply_name, reply_code));
|
/* refer logon request to the domain controller */
|
||||||
|
reply_code = 0x7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strupper(reply_name);
|
||||||
|
DEBUG(3,("GETDC request from %s(%s), reporting %s 0x%x token=%x\n",
|
||||||
|
machine,inet_ntoa(p->ip), reply_name, reply_code,token));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
DEBUG(3,("Unknown domain request %d\n",code));
|
DEBUG(3,("Unknown domain request %d\n",code));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bzero(outbuf,sizeof(outbuf));
|
bzero(outbuf,sizeof(outbuf));
|
||||||
q = outbuf;
|
q = outbuf;
|
||||||
SSVAL(q,0,reply_code);
|
SSVAL(q,0,reply_code);
|
||||||
q += 2;
|
q += 2;
|
||||||
if (add_slashes) {
|
|
||||||
|
if (token == 0xffff || /* LM 2.0 or later */
|
||||||
|
token == 0xfffe) /* WfWg networking */
|
||||||
|
{
|
||||||
|
if (add_slashes)
|
||||||
|
{
|
||||||
strcpy(q,"\\\\");
|
strcpy(q,"\\\\");
|
||||||
q += 2;
|
q += 2;
|
||||||
}
|
}
|
||||||
StrnCpy(q,reply_name,16);
|
strcpy(q, reply_name);
|
||||||
|
strupper(q);
|
||||||
q = skip_string(q,1);
|
q = skip_string(q,1);
|
||||||
|
|
||||||
if (reply_code == 0xC)
|
if (token == 0xffff) /* LM 2.0 or later */
|
||||||
{
|
|
||||||
if ( PTR_DIFF (q,outbuf) & 1 )
|
|
||||||
{
|
{
|
||||||
q++;
|
SSVAL(q,0,token);
|
||||||
}
|
|
||||||
|
|
||||||
PutUniCode(q,reply_name);
|
|
||||||
q += 2*(strlen(reply_name) + 1);
|
|
||||||
|
|
||||||
PutUniCode(q,lp_workgroup());
|
|
||||||
q += 2*(strlen(lp_workgroup()) + 1);
|
|
||||||
|
|
||||||
SIVAL(q,0,1);
|
|
||||||
q += 4;
|
|
||||||
SSVAL(q,0,0xFFFF);
|
|
||||||
q += 2;
|
q += 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SSVAL(q,0,0xFFFF);
|
SSVAL(q,0,0xFFFF);
|
||||||
q += 2;
|
q += 2;
|
||||||
|
|
||||||
send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
|
send_mailslot_reply(True, logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
|
||||||
myname,&dgram->source_name.name[0],0x20,0,p->ip,
|
myname,&dgram->source_name.name[0],0x20,0,p->ip,
|
||||||
*iface_ip(p->ip));
|
*iface_ip(p->ip));
|
||||||
}
|
}
|
||||||
|
@ -559,7 +559,7 @@ void listen_for_packets(BOOL run_election)
|
|||||||
Note that this currently sends all answers to port 138. thats the
|
Note that this currently sends all answers to port 138. thats the
|
||||||
wrong things to do! I should send to the requestors port. XXX
|
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,
|
BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname,
|
||||||
char *dstname,int src_type,int dest_type,
|
char *dstname,int src_type,int dest_type,
|
||||||
struct in_addr dest_ip,struct in_addr src_ip)
|
struct in_addr dest_ip,struct in_addr src_ip)
|
||||||
{
|
{
|
||||||
@ -576,7 +576,8 @@ BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
|
|||||||
|
|
||||||
update_name_trn_id();
|
update_name_trn_id();
|
||||||
|
|
||||||
dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
|
/* DIRECT GROUP or UNIQUE datagram */
|
||||||
|
dgram->header.msg_type = unique ? 0x10 : 0x11;
|
||||||
dgram->header.flags.node_type = M_NODE;
|
dgram->header.flags.node_type = M_NODE;
|
||||||
dgram->header.flags.first = True;
|
dgram->header.flags.first = True;
|
||||||
dgram->header.flags.more = False;
|
dgram->header.flags.more = False;
|
||||||
|
@ -155,6 +155,51 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
add the domain logon server and domain master browser names
|
||||||
|
|
||||||
|
this code was written so that several samba servers can co-operate in
|
||||||
|
sharing the task of (one server) being a domain master, and of being
|
||||||
|
domain logon servers.
|
||||||
|
|
||||||
|
**************************************************************************/
|
||||||
|
void add_domain_names(time_t t)
|
||||||
|
{
|
||||||
|
static time_t lastrun = 0;
|
||||||
|
struct subnet_record *d;
|
||||||
|
|
||||||
|
if (lastrun != 0 && t < lastrun + CHECK_TIME_ADD_DOM_NAMES * 60) return;
|
||||||
|
lastrun = t;
|
||||||
|
|
||||||
|
for (d = subnetlist; d; d = d->next)
|
||||||
|
{
|
||||||
|
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
|
||||||
|
struct nmb_name n;
|
||||||
|
|
||||||
|
if (lp_domain_logons() && work && work->log_state == LOGON_NONE)
|
||||||
|
{
|
||||||
|
make_nmb_name(&n,lp_workgroup(),0x1c,scope);
|
||||||
|
if (!find_name(d->namelist, &n, FIND_SELF))
|
||||||
|
{
|
||||||
|
DEBUG(0,("%s attempting to become logon server for %s %s\n",
|
||||||
|
timestring(), lp_workgroup(), inet_ntoa(d->bcast_ip)));
|
||||||
|
become_logon_server(d, work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lp_domain_master() && work && work->dom_state == DOMAIN_NONE)
|
||||||
|
{
|
||||||
|
make_nmb_name(&n,lp_workgroup(),0x1b,scope);
|
||||||
|
if (!find_name(d->namelist, &n, FIND_SELF))
|
||||||
|
{
|
||||||
|
DEBUG(1,("%s attempting to become logon server for %s %s\n",
|
||||||
|
timestring(), lp_workgroup(), inet_ntoa(d->bcast_ip)));
|
||||||
|
become_domain_master(d, work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
add the magic samba names, useful for finding samba servers
|
add the magic samba names, useful for finding samba servers
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@ -170,6 +215,7 @@ void add_my_names(void)
|
|||||||
for (d = subnetlist; d; d = d->next)
|
for (d = subnetlist; d; d = d->next)
|
||||||
{
|
{
|
||||||
BOOL wins = lp_wins_support() && ip_equal(d->bcast_ip,ipgrp);
|
BOOL wins = lp_wins_support() && ip_equal(d->bcast_ip,ipgrp);
|
||||||
|
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
|
||||||
|
|
||||||
add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE);
|
add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE);
|
||||||
add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE);
|
add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE);
|
||||||
@ -183,18 +229,13 @@ void add_my_names(void)
|
|||||||
add_netbios_entry(d,"__SAMBA__",0x20,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
|
add_netbios_entry(d,"__SAMBA__",0x20,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
|
||||||
add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
|
add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
|
||||||
|
|
||||||
if (lp_domain_logons()) {
|
if (lp_domain_logons() && work && work->log_state == LOGON_NONE)
|
||||||
/* XXXX the 0x1c is apparently something to do with domain logons */
|
|
||||||
add_my_name_entry(d, lp_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lp_domain_master() && (d = find_subnet(ipgrp)))
|
|
||||||
{
|
|
||||||
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
|
|
||||||
if (work && work->state == MST_NONE)
|
|
||||||
{
|
{
|
||||||
work->state = MST_DOMAIN_NONE;
|
become_logon_server(d, work);
|
||||||
become_master(d, work);
|
}
|
||||||
|
if (lp_domain_master() && work && work->dom_state == DOMAIN_NONE)
|
||||||
|
{
|
||||||
|
become_domain_master(d, work);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,8 @@ void reset_server(char *name, int state, struct in_addr ip)
|
|||||||
DEBUG(2,("sending reset to %s %s of state %d\n",
|
DEBUG(2,("sending reset to %s %s of state %d\n",
|
||||||
name,inet_ntoa(ip),state));
|
name,inet_ntoa(ip),state));
|
||||||
|
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
|
||||||
|
outbuf,PTR_DIFF(p,outbuf),
|
||||||
myname,name,0x20,0x1d,ip,*iface_ip(ip));
|
myname,name,0x20,0x1d,ip,*iface_ip(ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,7 +489,8 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
|
|||||||
int len = PTR_DIFF(p, outbuf);
|
int len = PTR_DIFF(p, outbuf);
|
||||||
debug_browse_data(outbuf, len);
|
debug_browse_data(outbuf, len);
|
||||||
}
|
}
|
||||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
|
||||||
|
outbuf,PTR_DIFF(p,outbuf),
|
||||||
myname,theirname,0x0,0x0,ip,*iface_ip(ip));
|
myname,theirname,0x0,0x0,ip,*iface_ip(ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,7 +572,7 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
|
|||||||
{
|
{
|
||||||
if (AM_MASTER(work))
|
if (AM_MASTER(work))
|
||||||
{
|
{
|
||||||
become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER);
|
unbecome_local_master(d,work,SV_TYPE_MASTER_BROWSER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,9 +300,7 @@ static void process(void)
|
|||||||
run_elections(t);
|
run_elections(t);
|
||||||
|
|
||||||
announce_host(t);
|
announce_host(t);
|
||||||
|
|
||||||
announce_master(t);
|
announce_master(t);
|
||||||
|
|
||||||
announce_remote(t);
|
announce_remote(t);
|
||||||
|
|
||||||
query_refresh_names(t);
|
query_refresh_names(t);
|
||||||
@ -314,6 +312,7 @@ static void process(void)
|
|||||||
write_browse_list(t);
|
write_browse_list(t);
|
||||||
do_browser_lists(t);
|
do_browser_lists(t);
|
||||||
check_master_browser(t);
|
check_master_browser(t);
|
||||||
|
add_domain_names(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Unix SMB/Netbios implementation.
|
Unix SMB/Netbios implementation.
|
||||||
Version 1.9.
|
Version 1.9.
|
||||||
@ -1672,7 +1673,8 @@ static BOOL api_RNetServerGetInfo(int cnum,uint16 vuid, char *param,char *data,
|
|||||||
|
|
||||||
if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
|
if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
|
||||||
for (i=0;i<count;i++)
|
for (i=0;i<count;i++)
|
||||||
if (strequal(servers[i].name,local_machine)) {
|
if (strequal(servers[i].name,local_machine))
|
||||||
|
{
|
||||||
servertype = servers[i].type;
|
servertype = servers[i].type;
|
||||||
strcpy(comment,servers[i].comment);
|
strcpy(comment,servers[i].comment);
|
||||||
}
|
}
|
||||||
@ -1742,8 +1744,10 @@ static BOOL api_NetWkstaGetInfo(int cnum,uint16 vuid, char *param,char *data,
|
|||||||
p = *rdata;
|
p = *rdata;
|
||||||
p2 = p + 22;
|
p2 = p + 22;
|
||||||
|
|
||||||
SIVAL(p,0,PTR_DIFF(p2,*rdata));
|
|
||||||
|
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* host name */
|
||||||
strcpy(p2,local_machine);
|
strcpy(p2,local_machine);
|
||||||
|
strupper(p2);
|
||||||
p2 = skip_string(p2,1);
|
p2 = skip_string(p2,1);
|
||||||
p += 4;
|
p += 4;
|
||||||
|
|
||||||
@ -1752,21 +1756,22 @@ static BOOL api_NetWkstaGetInfo(int cnum,uint16 vuid, char *param,char *data,
|
|||||||
p2 = skip_string(p2,1);
|
p2 = skip_string(p2,1);
|
||||||
p += 4;
|
p += 4;
|
||||||
|
|
||||||
SIVAL(p,0,PTR_DIFF(p2,*rdata));
|
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
|
||||||
strcpy(p2,lp_workgroup());
|
strcpy(p2,lp_workgroup());
|
||||||
|
strupper(p2);
|
||||||
p2 = skip_string(p2,1);
|
p2 = skip_string(p2,1);
|
||||||
p += 4;
|
p += 4;
|
||||||
|
|
||||||
SCVAL(p,0,MAJOR_VERSION);
|
SCVAL(p,0,MAJOR_VERSION); /* system version - e.g 4 in 4.1 */
|
||||||
SCVAL(p,1,MINOR_VERSION);
|
SCVAL(p,1,MINOR_VERSION); /* system version - e.g .1 in 4.1 */
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
SIVAL(p,0,PTR_DIFF(p2,*rdata));
|
SIVAL(p,0,PTR_DIFF(p2,*rdata));
|
||||||
strcpy(p2,lp_workgroup()); /* login domain?? */
|
strcpy(p2,lp_workgroup()); /* don't know. login domain?? */
|
||||||
p2 = skip_string(p2,1);
|
p2 = skip_string(p2,1);
|
||||||
p += 4;
|
p += 4;
|
||||||
|
|
||||||
SIVAL(p,0,PTR_DIFF(p2,*rdata));
|
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* don't know */
|
||||||
strcpy(p2,"");
|
strcpy(p2,"");
|
||||||
p2 = skip_string(p2,1);
|
p2 = skip_string(p2,1);
|
||||||
p += 4;
|
p += 4;
|
||||||
@ -1778,166 +1783,338 @@ static BOOL api_NetWkstaGetInfo(int cnum,uint16 vuid, char *param,char *data,
|
|||||||
return(True);
|
return(True);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
get info about a user
|
get info about a user
|
||||||
|
|
||||||
|
struct user_info_11 {
|
||||||
|
char usri11_name[21]; 0-20
|
||||||
|
char usri11_pad; 21
|
||||||
|
char *usri11_comment; 22-25
|
||||||
|
char *usri11_usr_comment; 26-29
|
||||||
|
unsigned short usri11_priv; 30-31
|
||||||
|
unsigned long usri11_auth_flags; 32-35
|
||||||
|
long usri11_password_age; 36-39
|
||||||
|
char *usri11_homedir; 40-43
|
||||||
|
char *usri11_parms; 44-47
|
||||||
|
long usri11_last_logon; 48-51
|
||||||
|
long usri11_last_logoff; 52-55
|
||||||
|
unsigned short usri11_bad_pw_count; 56-57
|
||||||
|
unsigned short usri11_num_logons; 58-59
|
||||||
|
char *usri11_logon_server; 60-63
|
||||||
|
unsigned short usri11_country_code; 64-65
|
||||||
|
char *usri11_workstations; 66-69
|
||||||
|
unsigned long usri11_max_storage; 70-73
|
||||||
|
unsigned short usri11_units_per_week; 74-75
|
||||||
|
unsigned char *usri11_logon_hours; 76-79
|
||||||
|
unsigned short usri11_code_page; 80-81
|
||||||
|
};
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
usri11_name specifies the user name for which information is retireved
|
||||||
|
|
||||||
|
usri11_pad aligns the next data structure element to a word boundary
|
||||||
|
|
||||||
|
usri11_comment is a null terminated ASCII comment
|
||||||
|
|
||||||
|
usri11_user_comment is a null terminated ASCII comment about the user
|
||||||
|
|
||||||
|
usri11_priv specifies the level of the privilege assigned to the user.
|
||||||
|
The possible values are:
|
||||||
|
|
||||||
|
Name Value Description
|
||||||
|
USER_PRIV_GUEST 0 Guest privilege
|
||||||
|
USER_PRIV_USER 1 User privilege
|
||||||
|
USER_PRV_ADMIN 2 Administrator privilege
|
||||||
|
|
||||||
|
usri11_auth_flags specifies the account operator privileges. The
|
||||||
|
possible values are:
|
||||||
|
|
||||||
|
Name Value Description
|
||||||
|
AF_OP_PRINT 0 Print operator
|
||||||
|
|
||||||
|
|
||||||
|
Leach, Naik [Page 28]
|
||||||
|
|
||||||
|
|
||||||
|
INTERNET-DRAFT CIFS Remote Admin Protocol January 10, 1997
|
||||||
|
|
||||||
|
|
||||||
|
AF_OP_COMM 1 Communications operator
|
||||||
|
AF_OP_SERVER 2 Server operator
|
||||||
|
AF_OP_ACCOUNTS 3 Accounts operator
|
||||||
|
|
||||||
|
|
||||||
|
usri11_password_age specifies how many seconds have elapsed since the
|
||||||
|
password was last changed.
|
||||||
|
|
||||||
|
usri11_home_dir points to a null terminated ASCII string that contains
|
||||||
|
the path name of the user's home directory.
|
||||||
|
|
||||||
|
usri11_parms points to a null terminated ASCII string that is set
|
||||||
|
aside for use by applications.
|
||||||
|
|
||||||
|
usri11_last_logon specifies the time when the user last logged on.
|
||||||
|
This value is stored as the number of seconds elapsed since
|
||||||
|
00:00:00, January 1, 1970.
|
||||||
|
|
||||||
|
usri11_last_logoff specifies the time when the user last logged off.
|
||||||
|
This value is stored as the number of seconds elapsed since
|
||||||
|
00:00:00, January 1, 1970. A value of 0 means the last logoff
|
||||||
|
time is unknown.
|
||||||
|
|
||||||
|
usri11_bad_pw_count specifies the number of incorrect passwords
|
||||||
|
entered since the last successful logon.
|
||||||
|
|
||||||
|
usri11_log1_num_logons specifies the number of times this user has
|
||||||
|
logged on. A value of -1 means the number of logons is unknown.
|
||||||
|
|
||||||
|
usri11_logon_server points to a null terminated ASCII string that
|
||||||
|
contains the name of the server to which logon requests are sent.
|
||||||
|
A null string indicates logon requests should be sent to the
|
||||||
|
domain controller.
|
||||||
|
|
||||||
|
usri11_country_code specifies the country code for the user's language
|
||||||
|
of choice.
|
||||||
|
|
||||||
|
usri11_workstations points to a null terminated ASCII string that
|
||||||
|
contains the names of workstations the user may log on from.
|
||||||
|
There may be up to 8 workstations, with the names separated by
|
||||||
|
commas. A null strings indicates there are no restrictions.
|
||||||
|
|
||||||
|
usri11_max_storage specifies the maximum amount of disk space the user
|
||||||
|
can occupy. A value of 0xffffffff indicates there are no
|
||||||
|
restrictions.
|
||||||
|
|
||||||
|
usri11_units_per_week specifies the equal number of time units into
|
||||||
|
which a week is divided. This value must be equal to 168.
|
||||||
|
|
||||||
|
usri11_logon_hours points to a 21 byte (168 bits) string that
|
||||||
|
specifies the time during which the user can log on. Each bit
|
||||||
|
represents one unique hour in a week. The first bit (bit 0, word
|
||||||
|
0) is Sunday, 0:00 to 0:59, the second bit (bit 1, word 0) is
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Leach, Naik [Page 29]
|
||||||
|
|
||||||
|
|
||||||
|
INTERNET-DRAFT CIFS Remote Admin Protocol January 10, 1997
|
||||||
|
|
||||||
|
|
||||||
|
Sunday, 1:00 to 1:59 and so on. A null pointer indicates there
|
||||||
|
are no restrictions.
|
||||||
|
|
||||||
|
usri11_code_page specifies the code page for the user's language of
|
||||||
|
choice
|
||||||
|
|
||||||
|
All of the pointers in this data structure need to be treated
|
||||||
|
specially. The pointer is a 32 bit pointer. The higher 16 bits need
|
||||||
|
to be ignored. The converter word returned in the parameters section
|
||||||
|
needs to be subtracted from the lower 16 bits to calculate an offset
|
||||||
|
into the return buffer where this ASCII string resides.
|
||||||
|
|
||||||
|
There is no auxiliary data in the response.
|
||||||
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define usri11_name 0
|
||||||
|
#define usri11_pad 21
|
||||||
|
#define usri11_comment 22
|
||||||
|
#define usri11_usr_comment 26
|
||||||
|
#define usri11_full_name 30
|
||||||
|
#define usri11_priv 34
|
||||||
|
#define usri11_auth_flags 36
|
||||||
|
#define usri11_password_age 40
|
||||||
|
#define usri11_homedir 44
|
||||||
|
#define usri11_parms 48
|
||||||
|
#define usri11_last_logon 52
|
||||||
|
#define usri11_last_logoff 56
|
||||||
|
#define usri11_bad_pw_count 60
|
||||||
|
#define usri11_num_logons 62
|
||||||
|
#define usri11_logon_server 64
|
||||||
|
#define usri11_country_code 68
|
||||||
|
#define usri11_workstations 70
|
||||||
|
#define usri11_max_storage 74
|
||||||
|
#define usri11_units_per_week 78
|
||||||
|
#define usri11_logon_hours 80
|
||||||
|
#define usri11_code_page 84
|
||||||
|
#define usri11_end 86
|
||||||
|
|
||||||
#define USER_PRIV_GUEST 0
|
#define USER_PRIV_GUEST 0
|
||||||
#define USER_PRIV_USER 1
|
#define USER_PRIV_USER 1
|
||||||
#define USER_PRIV_ADMIN 2
|
#define USER_PRIV_ADMIN 2
|
||||||
|
|
||||||
|
#define AF_OP_PRINT 0
|
||||||
|
#define AF_OP_COMM 1
|
||||||
|
#define AF_OP_SERVER 2
|
||||||
|
#define AF_OP_ACCOUNTS 3
|
||||||
|
|
||||||
static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data,
|
static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data,
|
||||||
int mdrcnt,int mprcnt,
|
int mdrcnt,int mprcnt,
|
||||||
char **rdata,char **rparam,
|
char **rdata,char **rparam,
|
||||||
int *rdata_len,int *rparam_len)
|
int *rdata_len,int *rparam_len)
|
||||||
{
|
{
|
||||||
char *str1 = param+2;
|
char *str1 = param+2;
|
||||||
char *str2 = skip_string(str1,1);
|
char *str2 = skip_string(str1,1);
|
||||||
char *UserName = skip_string(str2,1);
|
char *UserName = skip_string(str2,1);
|
||||||
char *p = skip_string(UserName,1);
|
char *p = skip_string(UserName,1);
|
||||||
int uLevel = SVAL(p,0);
|
int uLevel = SVAL(p,0);
|
||||||
char *p2;
|
char *p2;
|
||||||
|
|
||||||
*rparam_len = 6;
|
*rparam_len = 6;
|
||||||
*rparam = REALLOC(*rparam,*rparam_len);
|
*rparam = REALLOC(*rparam,*rparam_len);
|
||||||
|
|
||||||
/* check it's a supported varient */
|
/* check it's a supported varient */
|
||||||
if (strcmp(str1,"zWrLh") != 0) return False;
|
if (strcmp(str1,"zWrLh") != 0) return False;
|
||||||
switch( uLevel ) {
|
switch( uLevel )
|
||||||
case 0: p2 = "B21"; break;
|
{
|
||||||
case 1: p2 = "B21BB16DWzzWz"; break;
|
case 0: p2 = "B21"; break;
|
||||||
case 2: p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
|
case 1: p2 = "B21BB16DWzzWz"; break;
|
||||||
case 10: p2 = "B21Bzzz"; break;
|
case 2: p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
|
||||||
case 11: p2 = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
|
case 10: p2 = "B21Bzzz"; break;
|
||||||
default: return False;
|
case 11: p2 = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
|
||||||
}
|
default: return False;
|
||||||
if (strcmp(p2,str2) != 0) return False;
|
}
|
||||||
|
|
||||||
*rdata_len = mdrcnt + 1024;
|
if (strcmp(p2,str2) != 0) return False;
|
||||||
*rdata = REALLOC(*rdata,*rdata_len);
|
|
||||||
|
|
||||||
SSVAL(*rparam,0,NERR_Success);
|
*rdata_len = mdrcnt + 1024;
|
||||||
SSVAL(*rparam,2,0); /* converter word */
|
*rdata = REALLOC(*rdata,*rdata_len);
|
||||||
|
|
||||||
p = *rdata;
|
SSVAL(*rparam,0,NERR_Success);
|
||||||
p2 = p + 86;
|
SSVAL(*rparam,2,0); /* converter word */
|
||||||
|
|
||||||
memset(p,0,21);
|
p = *rdata;
|
||||||
strcpy(p,UserName);
|
p2 = p + usri11_end;
|
||||||
if (uLevel > 0) {
|
|
||||||
SCVAL(p,21,0);
|
|
||||||
*p2 = 0;
|
|
||||||
if (uLevel >= 10) {
|
|
||||||
SIVAL(p,22,PTR_DIFF(p2,p)); /* comment */
|
|
||||||
strcpy(p2,"<Comment>");
|
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
SIVAL(p,26,PTR_DIFF(p2,p)); /* user_comment */
|
|
||||||
strcpy(p2,"<UserComment>");
|
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
SIVAL(p,30,PTR_DIFF(p2,p)); /* full name */
|
|
||||||
strcpy(p2,"<FullName>");
|
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
}
|
|
||||||
if (uLevel == 11) { /* modelled after NTAS 3.51 reply */
|
|
||||||
SSVAL(p,34,
|
|
||||||
Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
|
|
||||||
SIVAL(p,36,0); /* auth flags */
|
|
||||||
SIVALS(p,40,-1); /* password age */
|
|
||||||
SIVAL(p,44,PTR_DIFF(p2,p)); /* home dir */
|
|
||||||
if (*lp_logon_path())
|
|
||||||
{
|
|
||||||
strcpy(p2,lp_logon_path());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy(p2,"\\\\%L\\HOMES");
|
|
||||||
standard_sub_basic(p2);
|
|
||||||
}
|
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
SIVAL(p,48,PTR_DIFF(p2,p)); /* parms */
|
|
||||||
strcpy(p2,"");
|
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
SIVAL(p,52,0); /* last logon */
|
|
||||||
SIVAL(p,56,0); /* last logoff */
|
|
||||||
SSVALS(p,60,-1); /* bad pw counts */
|
|
||||||
SSVALS(p,62,-1); /* num logons */
|
|
||||||
SIVAL(p,64,PTR_DIFF(p2,p)); /* logon server */
|
|
||||||
strcpy(p2,"\\\\*");
|
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
SSVAL(p,68,0); /* country code */
|
|
||||||
|
|
||||||
SIVAL(p,70,PTR_DIFF(p2,p)); /* workstations */
|
memset(p,0,21);
|
||||||
strcpy(p2,"");
|
strcpy(p+usri11_name,UserName); /* 21 bytes - user name */
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
|
|
||||||
SIVALS(p,74,-1); /* max storage */
|
if (uLevel > 0)
|
||||||
SSVAL(p,78,168); /* units per week */
|
{
|
||||||
SIVAL(p,80,PTR_DIFF(p2,p)); /* logon hours */
|
SCVAL(p,usri11_pad,0); /* padding - 1 byte */
|
||||||
memset(p2,-1,21);
|
*p2 = 0;
|
||||||
SCVAL(p2,21,0); /* fix zero termination */
|
}
|
||||||
p2 = skip_string(p2,1);
|
if (uLevel >= 10)
|
||||||
|
{
|
||||||
|
SIVAL(p,usri11_comment,PTR_DIFF(p2,p)); /* comment */
|
||||||
|
strcpy(p2,"Comment");
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
|
||||||
SSVAL(p,84,0); /* code page */
|
SIVAL(p,usri11_usr_comment,PTR_DIFF(p2,p)); /* user_comment */
|
||||||
}
|
strcpy(p2,"UserComment");
|
||||||
if (uLevel == 1 || uLevel == 2) {
|
p2 = skip_string(p2,1);
|
||||||
memset(p+22,' ',16); /* password */
|
|
||||||
SIVALS(p,38,-1); /* password age */
|
|
||||||
SSVAL(p,42,
|
|
||||||
Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
|
|
||||||
SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
|
|
||||||
if (*lp_logon_path())
|
|
||||||
{
|
|
||||||
strcpy(p2,lp_logon_path());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy(p2,"\\\\%L\\HOMES");
|
|
||||||
standard_sub_basic(p2);
|
|
||||||
}
|
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
|
|
||||||
*p2++ = 0;
|
|
||||||
SSVAL(p,52,0); /* flags */
|
|
||||||
SIVAL(p,54,0); /* script_path */
|
|
||||||
if (uLevel == 2) {
|
|
||||||
SIVAL(p,60,0); /* auth_flags */
|
|
||||||
SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
|
|
||||||
strcpy(p2,"<Full Name>");
|
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
SIVAL(p,68,0); /* urs_comment */
|
|
||||||
SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
|
|
||||||
strcpy(p2,"");
|
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
SIVAL(p,76,0); /* workstations */
|
|
||||||
SIVAL(p,80,0); /* last_logon */
|
|
||||||
SIVAL(p,84,0); /* last_logoff */
|
|
||||||
SIVALS(p,88,-1); /* acct_expires */
|
|
||||||
SIVALS(p,92,-1); /* max_storage */
|
|
||||||
SSVAL(p,96,168); /* units_per_week */
|
|
||||||
SIVAL(p,98,PTR_DIFF(p2,*rdata)); /* logon_hours */
|
|
||||||
memset(p2,-1,21);
|
|
||||||
p2 += 21;
|
|
||||||
SSVALS(p,102,-1); /* bad_pw_count */
|
|
||||||
SSVALS(p,104,-1); /* num_logons */
|
|
||||||
SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
|
|
||||||
strcpy(p2,"\\\\%L");
|
|
||||||
standard_sub_basic(p2);
|
|
||||||
p2 = skip_string(p2,1);
|
|
||||||
SSVAL(p,110,49); /* country_code */
|
|
||||||
SSVAL(p,112,860); /* code page */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*rdata_len = PTR_DIFF(p2,*rdata);
|
/* EEK! the cifsrap.txt doesn't have this in!!!! */
|
||||||
|
SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */
|
||||||
|
#if 0
|
||||||
|
strcpy(p2,"FullName");
|
||||||
|
#endif
|
||||||
|
strcpy(p2,UserName); /* suggest copying the user name, for now... */
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
}
|
||||||
|
if (uLevel == 11) /* modelled after NTAS 3.51 reply */
|
||||||
|
{
|
||||||
|
SSVAL(p,usri11_priv,Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
|
||||||
|
SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
|
||||||
|
SIVALS(p,usri11_password_age,0xffffffff); /* password age */
|
||||||
|
SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
|
||||||
|
if (*lp_logon_path())
|
||||||
|
{
|
||||||
|
strcpy(p2,lp_logon_path());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(p2,"\\\\%L\\%U");
|
||||||
|
}
|
||||||
|
standard_sub_basic(p2);
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
|
||||||
|
strcpy(p2,"");
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
SIVAL(p,usri11_last_logon,0); /* last logon */
|
||||||
|
SIVAL(p,usri11_last_logoff,0); /* last logoff */
|
||||||
|
SSVALS(p,usri11_bad_pw_count,0xffffffff); /* bad pw counts */
|
||||||
|
SSVALS(p,usri11_num_logons,0xffffffff); /* num logons */
|
||||||
|
SIVAL(p,usri11_logon_server,PTR_DIFF(p2,p)); /* logon server */
|
||||||
|
strcpy(p2,"\\\\*");
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
SSVAL(p,usri11_country_code,0); /* country code */
|
||||||
|
|
||||||
SSVAL(*rparam,4,*rdata_len); /* is this right?? */
|
SIVAL(p,usri11_workstations,PTR_DIFF(p2,p)); /* workstations */
|
||||||
|
strcpy(p2,"");
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
|
||||||
return(True);
|
SIVALS(p,usri11_max_storage,0xffffffff); /* max storage */
|
||||||
|
SSVAL(p,usri11_units_per_week,168); /* units per week */
|
||||||
|
SIVAL(p,usri11_logon_hours,PTR_DIFF(p2,p)); /* logon hours */
|
||||||
|
|
||||||
|
/* a simple way to get logon hours at all times. */
|
||||||
|
memset(p2,0xff,21);
|
||||||
|
SCVAL(p2,21,0); /* fix zero termination */
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
|
||||||
|
SSVAL(p,usri11_code_page,0); /* code page */
|
||||||
|
}
|
||||||
|
if (uLevel == 1 || uLevel == 2)
|
||||||
|
{
|
||||||
|
memset(p+22,' ',16); /* password */
|
||||||
|
SIVALS(p,38,-1); /* password age */
|
||||||
|
SSVAL(p,42,
|
||||||
|
Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
|
||||||
|
SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
|
||||||
|
if (*lp_logon_path())
|
||||||
|
{
|
||||||
|
strcpy(p2,lp_logon_path());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(p2,"\\\\%L\\%U");
|
||||||
|
}
|
||||||
|
standard_sub_basic(p2);
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
|
||||||
|
*p2++ = 0;
|
||||||
|
SSVAL(p,52,0); /* flags */
|
||||||
|
SIVAL(p,54,0); /* script_path */
|
||||||
|
if (uLevel == 2)
|
||||||
|
{
|
||||||
|
SIVAL(p,60,0); /* auth_flags */
|
||||||
|
SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
|
||||||
|
strcpy(p2,"<Full Name>");
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
SIVAL(p,68,0); /* urs_comment */
|
||||||
|
SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
|
||||||
|
strcpy(p2,"");
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
SIVAL(p,76,0); /* workstations */
|
||||||
|
SIVAL(p,80,0); /* last_logon */
|
||||||
|
SIVAL(p,84,0); /* last_logoff */
|
||||||
|
SIVALS(p,88,-1); /* acct_expires */
|
||||||
|
SIVALS(p,92,-1); /* max_storage */
|
||||||
|
SSVAL(p,96,168); /* units_per_week */
|
||||||
|
SIVAL(p,98,PTR_DIFF(p2,*rdata)); /* logon_hours */
|
||||||
|
memset(p2,-1,21);
|
||||||
|
p2 += 21;
|
||||||
|
SSVALS(p,102,-1); /* bad_pw_count */
|
||||||
|
SSVALS(p,104,-1); /* num_logons */
|
||||||
|
SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
|
||||||
|
strcpy(p2,"\\\\%L");
|
||||||
|
standard_sub_basic(p2);
|
||||||
|
p2 = skip_string(p2,1);
|
||||||
|
SSVAL(p,110,49); /* country_code */
|
||||||
|
SSVAL(p,112,860); /* code page */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*rdata_len = PTR_DIFF(p2,*rdata);
|
||||||
|
|
||||||
|
SSVAL(*rparam,4,*rdata_len); /* is this right?? */
|
||||||
|
|
||||||
|
return(True);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
get groups that a user is a member of
|
get groups that a user is a member of
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
@ -2016,9 +2193,8 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data,
|
|||||||
desc.subformat = NULL;
|
desc.subformat = NULL;
|
||||||
desc.format = str2;
|
desc.format = str2;
|
||||||
|
|
||||||
|
if (init_package(&desc,1,0))
|
||||||
|
{
|
||||||
if (init_package(&desc,1,0)) {
|
|
||||||
PACKI(&desc,"W",0); /* code */
|
PACKI(&desc,"W",0); /* code */
|
||||||
PACKS(&desc,"B21",name); /* eff. name */
|
PACKS(&desc,"B21",name); /* eff. name */
|
||||||
PACKS(&desc,"B",""); /* pad */
|
PACKS(&desc,"B",""); /* pad */
|
||||||
@ -2027,7 +2203,7 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data,
|
|||||||
PACKI(&desc,"D",0); /* auth flags XXX */
|
PACKI(&desc,"D",0); /* auth flags XXX */
|
||||||
PACKI(&desc,"W",0); /* num logons */
|
PACKI(&desc,"W",0); /* num logons */
|
||||||
PACKI(&desc,"W",0); /* bad pw count */
|
PACKI(&desc,"W",0); /* bad pw count */
|
||||||
PACKI(&desc,"D",-1); /* last logon */
|
PACKI(&desc,"D",0); /* last logon */
|
||||||
PACKI(&desc,"D",-1); /* last logoff */
|
PACKI(&desc,"D",-1); /* last logoff */
|
||||||
PACKI(&desc,"D",-1); /* logoff time */
|
PACKI(&desc,"D",-1); /* logoff time */
|
||||||
PACKI(&desc,"D",-1); /* kickoff time */
|
PACKI(&desc,"D",-1); /* kickoff time */
|
||||||
@ -2043,7 +2219,7 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data,
|
|||||||
}
|
}
|
||||||
PACKS(&desc,"z",lp_workgroup());/* domain */
|
PACKS(&desc,"z",lp_workgroup());/* domain */
|
||||||
PACKS(&desc,"z",lp_logon_script()); /* script path */
|
PACKS(&desc,"z",lp_logon_script()); /* script path */
|
||||||
PACKI(&desc,"D",0); /* reserved */
|
PACKI(&desc,"D",0x00000000); /* reserved */
|
||||||
}
|
}
|
||||||
|
|
||||||
*rdata_len = desc.usedlen;
|
*rdata_len = desc.usedlen;
|
||||||
|
@ -2659,32 +2659,67 @@ int reply_lanman2(char *outbuf)
|
|||||||
return (smb_len(outbuf)+4);
|
return (smb_len(outbuf)+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
reply for the nt protocol
|
reply for the nt protocol
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
int reply_nt1(char *outbuf)
|
int reply_nt1(char *outbuf)
|
||||||
{
|
{
|
||||||
int capabilities=0x300; /* has dual names + lock_and_read */
|
/* dual names + lock_and_read + nt SMBs + remote API calls */
|
||||||
|
int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
|
||||||
|
/*
|
||||||
|
other valid capabilities which we may support at some time...
|
||||||
|
CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
|
||||||
|
CAP_LARGE_FILES|CAP_LARGE_READX|
|
||||||
|
CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
|
||||||
|
*/
|
||||||
|
|
||||||
int secword=0;
|
int secword=0;
|
||||||
BOOL doencrypt = SMBENCRYPT();
|
BOOL doencrypt = SMBENCRYPT();
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
|
int data_len;
|
||||||
|
int encrypt_len;
|
||||||
|
char challenge_len = 8;
|
||||||
|
|
||||||
|
if (lp_readraw() && lp_writeraw())
|
||||||
|
{
|
||||||
|
capabilities |= CAP_RAW_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
if (lp_security()>=SEC_USER) secword |= 1;
|
if (lp_security()>=SEC_USER) secword |= 1;
|
||||||
if (doencrypt) secword |= 2;
|
if (doencrypt) secword |= 2;
|
||||||
|
|
||||||
set_message(outbuf,17,doencrypt?8:0,True);
|
/* decide where (if) to put the encryption challenge, and
|
||||||
|
follow it with the OEM'd domain name
|
||||||
|
*/
|
||||||
|
encrypt_len = doencrypt?challenge_len:0;
|
||||||
|
#if UNICODE
|
||||||
|
data_len = encrypt_len + 2*(strlen(lp_workgroup())+1);
|
||||||
|
#else
|
||||||
|
data_len = encrypt_len + strlen(lp_workgroup()) + 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
set_message(outbuf,17,data_len,True);
|
||||||
|
|
||||||
|
#if UNICODE
|
||||||
|
/* put the OEM'd domain name */
|
||||||
|
PutUniCode(smb_buf(outbuf)+encrypt_len,lp_workgroup());
|
||||||
|
#else
|
||||||
|
strcpy(smb_buf(outbuf)+encrypt_len, lp_workgroup());
|
||||||
|
#endif
|
||||||
|
|
||||||
CVAL(outbuf,smb_vwv1) = secword;
|
CVAL(outbuf,smb_vwv1) = secword;
|
||||||
#ifdef SMB_PASSWD
|
#ifdef SMB_PASSWD
|
||||||
/* Create a token value and add it to the outgoing packet. */
|
/* Create a token value and add it to the outgoing packet. */
|
||||||
if (doencrypt) {
|
if (doencrypt)
|
||||||
|
{
|
||||||
generate_next_challenge(smb_buf(outbuf));
|
generate_next_challenge(smb_buf(outbuf));
|
||||||
|
|
||||||
/* Tell the nt machine how long the challenge is. */
|
/* Tell the nt machine how long the challenge is. */
|
||||||
SSVALS(outbuf,smb_vwv16+1,8);
|
SSVALS(outbuf,smb_vwv16+1,challenge_len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
|
|
||||||
|
|
||||||
Protocol = PROTOCOL_NT1;
|
Protocol = PROTOCOL_NT1;
|
||||||
|
|
||||||
if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
|
if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
|
||||||
@ -2694,21 +2729,19 @@ int reply_nt1(char *outbuf)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lp_readraw() && lp_writeraw())
|
|
||||||
capabilities |= 1;
|
|
||||||
|
|
||||||
SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
|
SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
|
||||||
SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
|
SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
|
||||||
SIVAL(outbuf,smb_vwv3+1,0xFFFF); /* max buffer */
|
SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
|
||||||
SIVAL(outbuf,smb_vwv5+1,0xFFFF); /* raw size */
|
SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
|
||||||
|
SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
|
||||||
SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
|
SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
|
||||||
put_long_date(outbuf+smb_vwv11+1,t);
|
put_long_date(outbuf+smb_vwv11+1,t);
|
||||||
SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
|
SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
|
||||||
|
SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
|
||||||
|
|
||||||
return (smb_len(outbuf)+4);
|
return (smb_len(outbuf)+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* these are the protocol lists used for auto architecture detection:
|
/* these are the protocol lists used for auto architecture detection:
|
||||||
|
|
||||||
WinNT 3.51:
|
WinNT 3.51:
|
||||||
|
Loading…
Reference in New Issue
Block a user