mirror of
https://github.com/samba-team/samba.git
synced 2025-03-03 12:58:35 +03:00
sync 3.0 branch with head
(This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290)
This commit is contained in:
parent
669a39fae3
commit
b2edf254ed
98
WHATSNEW.txt
98
WHATSNEW.txt
@ -1,6 +1,104 @@
|
||||
WHATS NEW IN Samba 3.0 alphaX
|
||||
=============================
|
||||
|
||||
Changes in alpha19
|
||||
- Heavy registry updates (jerry)
|
||||
- Use 850 as the default DOS character set in smb.conf (tpot)
|
||||
- printer fixes - removed encoding of queueid in job number (jra)
|
||||
- A lot of small fixes (jra)
|
||||
- virtual registry framework with initial printing hooks (jerry)
|
||||
- Don't crash on setfileinfo on printer fsp(jra)
|
||||
- fixed line buffer mode in XFILE(jra)
|
||||
- update samba.schema from 2.2 (jerry,idra)
|
||||
- Fix problem with oplock breaks and win2k -
|
||||
noticed by Lev Iserovich <lev@ciprico.com> (jra)
|
||||
- Give different error message when PDC is down -
|
||||
thanks to Mark Kaplan from Quantum (abartlet)
|
||||
- Add wrapper for dup2() (abartlet)
|
||||
- Update smbgroupedit to document -d - thanks to metze (abartlet)
|
||||
- Support weird behaviour used by win9x pass-through auth (abartlet,tpot)
|
||||
- Support for duplicating stderr in log files (abartlet)
|
||||
- Move startup time initialisation to server.c (abartlet)
|
||||
- *A lot* of fixes and cleanups (abartlet)
|
||||
- Fix up compiler warnings (abartlet)
|
||||
- Few small fixes (tpot)
|
||||
- Renamed new_cli_netlogon_* -> cli_netlogon_* (tpot)
|
||||
- Fixed segfault in net time when host is unavailable (tridge)
|
||||
- Ensure to be root when opening printer backend tdb (jra)
|
||||
- Merges from APPLIANCE_HEAD (tpot,jerry)
|
||||
- configure updates (tridge)
|
||||
- particularly getgrouplist() (tridge)
|
||||
- Make sure to be root when accessing pdb (abartlet)
|
||||
- Better PAM error message (abartlet)
|
||||
- Support for pdbedit to query account policy values (abartlet)
|
||||
- Fix few typos (mimir, abartlet)
|
||||
- Allow one to create trusting domain account using smbpasswd (mimir,abartlet)
|
||||
- 'Net rpc trustdom list' (mimir, abartlet)
|
||||
- Fix fallback to anonymous connection (mimir, abartlet)
|
||||
- Add debugging info to secrets.c (mimir, abartlet)
|
||||
- Fix for pdb_ldap and OpenLDAP 2.1
|
||||
- Added support in swat to determine whether winbind is running (idra)
|
||||
- Add 'hide unwritable' option (idra)
|
||||
- Correct pickup of [homes] share after subsequent session setups (abartlet)
|
||||
- Update rebind code in pdb_ldap (abartlet)
|
||||
- Add some info levels to RPC srvsvc code -
|
||||
thanks to Nigel Williams" <nigel@veritas.com> (abartlet)
|
||||
- Small doc fixes (tridge)
|
||||
- good security patch from Timothy.Sell@unisys.com (tridge)
|
||||
- fix minor nits in nmbd from adtam@cup.hp.com (tridge)
|
||||
- make sure async dns nmbd child dies (tridge)
|
||||
- interim fix for nmbd not registering DOMAIN#1b (tridge)
|
||||
- fix for smbtar filename matching (tridge)
|
||||
- Better quote handling in smb.conf (abartlet)
|
||||
- Support browsers setting multiple languages in swat (idra)
|
||||
- Changed str_list_make to be able to use a different separator string (idra)
|
||||
- Remove use of strtof because of portability issues (idra)
|
||||
- Common popt definition for -d option (tpot)
|
||||
- Samsync support to insert account info into the pdb (tpot)
|
||||
- Don't hide unwritable dirs when 'hide unwritable' is enabled -
|
||||
suggested by Alexander Oswald <oswald@is.haw-hamburg.de> (idra)
|
||||
- Fix for handling sparse files in smbd (tridge)
|
||||
- Merges from 2_2 (jerry)
|
||||
- Add cvslog.pl file
|
||||
- Minor printer fixes (jerry)
|
||||
- Fix SID lookup code to never do recursive winbind (abartlet)
|
||||
- Fix SID lookup code to never use algoritmic rid for fixed mappings (abartlet)
|
||||
- Cascaded VFS (Alexander Bokovoy, idra)
|
||||
- Optimisations when in ADS mode (tridge)
|
||||
- Try netbios-less connections when in ADS mode (tridge)
|
||||
- Minor ADS tweaks (tridge)
|
||||
- Fix plaintext passwords with win2k (tridge)
|
||||
- 'net ads info' reports IP of LDAP server (tridge)
|
||||
- Add LSA RPC 0x2E, lsa_query_info2 (jmcd)
|
||||
- Add 'smb ports = ' option (tridge)
|
||||
- Various small fixes (tridge)
|
||||
- Add 'disable netbios = yes/no' (tridge)
|
||||
- Passdb security checks (abartlet)
|
||||
- Large winbind updates (abartlet)
|
||||
- Moved rpc client routines from libsmb to rpc_client (tpot)
|
||||
- Few nmbd fixes (jmcd)
|
||||
- Fix swat to handle new debug level (idra)
|
||||
- Fix name length in namequeries (tridge)
|
||||
- Netbios-less setup ADS fixes (tridge)
|
||||
- Add SAMR 0x3e, which is samr_connect4 (jmcd)
|
||||
- Add consts to passdb (abartlet)
|
||||
- Don't client binaries depend on libs they don't use -
|
||||
patch from Steve Langasek <vorlon@netexpress.net> (abartlet)
|
||||
- Printing change notification (merged from HEAD_APPLIANCE) (jerry)
|
||||
- fix delete printer driver (from HEAD_APPLIANCE) (jerry)
|
||||
- Added pdb_xml and pdb_mysql (jelmer)
|
||||
- Update pdb_test (jelmer)
|
||||
- Fix security issues with %m (abartlet)
|
||||
- Add client side support for samr connect4 (0x3e) (jmcd)
|
||||
- Add lsa 0x2e (queryinfo2) client side (jmcd)
|
||||
- Support for service joins from win2k AND use SPNEGO (jmcd)
|
||||
- pdbedit -i and -e fix, add -b (idra)
|
||||
- textdocs converted to sgml (jelmer, jerry)
|
||||
- Merge netbios namecache code from APPLIANCE_HEAD (tpot)
|
||||
- Fix segs in new NTLMSSP code (abartlet)
|
||||
- Always make guest rid 501 (abartlet)
|
||||
|
||||
|
||||
Changes in alpha18
|
||||
- huge number of changes! really too many to list ... (and its 1am
|
||||
here, and I'm too tired)
|
||||
|
@ -395,33 +395,33 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
|
||||
{
|
||||
case SEC_DOMAIN:
|
||||
DEBUG(5,("Making default auth method list for security=domain\n"));
|
||||
auth_method_list = str_list_make("guest sam ntdomain");
|
||||
auth_method_list = str_list_make("guest sam winbind ntdomain", NULL);
|
||||
break;
|
||||
case SEC_SERVER:
|
||||
DEBUG(5,("Making default auth method list for security=server\n"));
|
||||
auth_method_list = str_list_make("guest sam smbserver");
|
||||
auth_method_list = str_list_make("guest sam smbserver", NULL);
|
||||
break;
|
||||
case SEC_USER:
|
||||
if (lp_encrypted_passwords()) {
|
||||
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n"));
|
||||
auth_method_list = str_list_make("guest sam");
|
||||
auth_method_list = str_list_make("guest sam", NULL);
|
||||
} else {
|
||||
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
|
||||
auth_method_list = str_list_make("guest unix");
|
||||
auth_method_list = str_list_make("guest unix", NULL);
|
||||
}
|
||||
break;
|
||||
case SEC_SHARE:
|
||||
if (lp_encrypted_passwords()) {
|
||||
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
|
||||
auth_method_list = str_list_make("guest sam");
|
||||
auth_method_list = str_list_make("guest sam", NULL);
|
||||
} else {
|
||||
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n"));
|
||||
auth_method_list = str_list_make("guest unix");
|
||||
auth_method_list = str_list_make("guest unix", NULL);
|
||||
}
|
||||
break;
|
||||
case SEC_ADS:
|
||||
DEBUG(5,("Making default auth method list for security=ADS\n"));
|
||||
auth_method_list = str_list_make("guest sam ads ntdomain");
|
||||
auth_method_list = str_list_make("guest sam ads winbind ntdomain", NULL);
|
||||
break;
|
||||
default:
|
||||
DEBUG(5,("Unknown auth method!\n"));
|
||||
|
@ -29,6 +29,88 @@ BOOL global_machine_password_needs_changing = False;
|
||||
extern pstring global_myname;
|
||||
extern userdom_struct current_user_info;
|
||||
|
||||
|
||||
/*
|
||||
resolve the name of a DC in ways appropriate for an ADS domain mode
|
||||
an ADS domain may not have Netbios enabled at all, so this is
|
||||
quite different from the RPC case
|
||||
Note that we ignore the 'server' parameter here. That has the effect of using
|
||||
the 'ADS server' smb.conf parameter, which is what we really want anyway
|
||||
*/
|
||||
static NTSTATUS ads_resolve_dc(fstring remote_machine,
|
||||
struct in_addr *dest_ip)
|
||||
{
|
||||
ADS_STRUCT *ads;
|
||||
ads = ads_init_simple();
|
||||
if (!ads) {
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
DEBUG(4,("ads_resolve_dc: realm=%s\n", ads->config.realm));
|
||||
|
||||
ads->auth.no_bind = 1;
|
||||
|
||||
#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
|
||||
|
||||
fstrcpy(remote_machine, ads->config.ldap_server_name);
|
||||
strupper(remote_machine);
|
||||
*dest_ip = ads->ldap_ip;
|
||||
ads_destroy(&ads);
|
||||
|
||||
if (!*remote_machine || is_zero_ip(*dest_ip)) {
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
DEBUG(4,("ads_resolve_dc: using server='%s' IP=%s\n",
|
||||
remote_machine, inet_ntoa(*dest_ip)));
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
resolve the name of a DC in ways appropriate for RPC domain mode
|
||||
this relies on the server supporting netbios and port 137 not being
|
||||
firewalled
|
||||
*/
|
||||
static NTSTATUS rpc_resolve_dc(const char *server,
|
||||
fstring remote_machine,
|
||||
struct in_addr *dest_ip)
|
||||
{
|
||||
if (is_ipaddress(server)) {
|
||||
struct in_addr to_ip = *interpret_addr2(server);
|
||||
|
||||
/* we need to know the machines netbios name - this is a lousy
|
||||
way to find it, but until we have a RPC call that does this
|
||||
it will have to do */
|
||||
if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) {
|
||||
DEBUG(2, ("connect_to_domain_password_server: Can't "
|
||||
"resolve name for IP %s\n", server));
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
*dest_ip = to_ip;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
fstrcpy(remote_machine, server);
|
||||
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));
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
DEBUG(4,("rpc_resolve_dc: using server='%s' IP=%s\n",
|
||||
remote_machine, inet_ntoa(*dest_ip)));
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to a remote server for domain security authenticaion.
|
||||
*
|
||||
@ -50,37 +132,22 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
|
||||
fstring remote_machine;
|
||||
NTSTATUS result;
|
||||
|
||||
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 NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
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 NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
if (lp_security() == SEC_ADS) {
|
||||
result = ads_resolve_dc(remote_machine, &dest_ip);
|
||||
} else {
|
||||
fstrcpy(remote_machine, server);
|
||||
result = rpc_resolve_dc(server, remote_machine, &dest_ip);
|
||||
}
|
||||
|
||||
standard_sub_basic(current_user_info.smb_name, remote_machine, sizeof(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));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(2,("connect_to_domain_password_server: unable to resolve DC: %s\n",
|
||||
nt_errstr(result)));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
if (ismyip(dest_ip)) {
|
||||
DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n",
|
||||
remote_machine));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
/* TODO: Send a SAMLOGON request to determine whether this is a valid
|
||||
@ -98,11 +165,11 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
|
||||
*/
|
||||
|
||||
if (!grab_server_mutex(server))
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
|
||||
/* Attempt connection */
|
||||
result = cli_full_connection(cli, global_myname, server,
|
||||
&dest_ip, 0, "IPC$", "IPC", "", "", "", 0);
|
||||
result = cli_full_connection(cli, global_myname, remote_machine,
|
||||
&dest_ip, 0, "IPC$", "IPC", "", "", "",0);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
release_server_mutex();
|
||||
@ -129,7 +196,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
|
||||
cli_ulogoff(*cli);
|
||||
cli_shutdown(*cli);
|
||||
release_server_mutex();
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
snprintf((*cli)->mach_acct, sizeof((*cli)->mach_acct) - 1, "%s$", setup_creds_as);
|
||||
@ -139,7 +206,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
result = new_cli_nt_setup_creds(*cli, sec_chan, trust_passwd);
|
||||
result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \
|
||||
@ -174,10 +241,10 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli,
|
||||
*/
|
||||
|
||||
if (is_zero_ip(*ip))
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
|
||||
if (!lookup_dc_name(global_myname, domain, ip, dc_name))
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
|
||||
return connect_to_domain_password_server(cli, dc_name, setup_creds_as, sec_chan, trust_passwd);
|
||||
}
|
||||
@ -196,7 +263,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
||||
struct in_addr *ip_list = NULL;
|
||||
int count = 0;
|
||||
int i;
|
||||
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
|
||||
time_t time_now = time(NULL);
|
||||
BOOL use_pdc_only = False;
|
||||
|
||||
@ -212,7 +279,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
||||
use_pdc_only = True;
|
||||
|
||||
if (!get_dc_list(use_pdc_only, domain, &ip_list, &count))
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
|
||||
/*
|
||||
* Firstly try and contact a PDC/BDC who has the same
|
||||
@ -288,7 +355,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
||||
fstring remote_machine;
|
||||
NET_USER_INFO_3 info3;
|
||||
struct cli_state *cli = NULL;
|
||||
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
|
||||
|
||||
/*
|
||||
* At this point, smb_apasswd points to the lanman response to
|
||||
@ -300,7 +367,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
||||
|
||||
while (!NT_STATUS_IS_OK(nt_status) &&
|
||||
next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) {
|
||||
if(strequal(remote_machine, "*")) {
|
||||
if(lp_security() != SEC_ADS && strequal(remote_machine, "*")) {
|
||||
nt_status = find_connect_pdc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time);
|
||||
} else {
|
||||
nt_status = connect_to_domain_password_server(&cli, remote_machine, setup_creds_as, sec_chan, trust_passwd);
|
||||
@ -503,7 +570,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
|
||||
#ifdef DEBUG_PASSWORD
|
||||
DEBUG(100, ("Trust password for domain %s is %s\n", user_info->domain.str, trust_password));
|
||||
#endif
|
||||
E_md4hash((uchar *)trust_password, trust_md4_password);
|
||||
E_md4hash(trust_password, trust_md4_password);
|
||||
SAFE_FREE(trust_password);
|
||||
|
||||
#if 0
|
||||
|
@ -107,7 +107,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
|
||||
memcpy(client_response, ntv2_response.data, sizeof(client_response));
|
||||
|
||||
ntv2_owf_gen(part_passwd, user, domain, kr);
|
||||
SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, (char *)value_from_encryption);
|
||||
SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, value_from_encryption);
|
||||
if (user_sess_key != NULL)
|
||||
{
|
||||
SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key);
|
||||
@ -232,11 +232,26 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
|
||||
{
|
||||
return NT_STATUS_OK;
|
||||
} else {
|
||||
if (lp_ntlm_auth()) {
|
||||
/* Apparently NT accepts NT responses in the LM feild
|
||||
- I think this is related to Win9X pass-though authenticaion
|
||||
*/
|
||||
DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM feild\n"));
|
||||
if (smb_pwd_check_ntlmv1(user_info->lm_resp,
|
||||
nt_pw, auth_context->challenge,
|
||||
user_sess_key))
|
||||
{
|
||||
return NT_STATUS_OK;
|
||||
} else {
|
||||
DEBUG(3,("sam_password_ok: NT MD4 password in LM feild failed for user %s\n",pdb_get_username(sampass)));
|
||||
return NT_STATUS_WRONG_PASSWORD;
|
||||
}
|
||||
}
|
||||
DEBUG(4,("sam_password_ok: LM password check failed for user %s\n",pdb_get_username(sampass)));
|
||||
return NT_STATUS_WRONG_PASSWORD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Should not be reached, but if they send nothing... */
|
||||
DEBUG(3,("sam_password_ok: NEITHER LanMan nor NT password supplied for user %s\n",pdb_get_username(sampass)));
|
||||
return NT_STATUS_WRONG_PASSWORD;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_AUTH
|
||||
|
||||
extern fstring remote_machine;
|
||||
extern pstring global_myname;
|
||||
|
||||
/****************************************************************************
|
||||
@ -394,7 +393,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
|
||||
|
||||
ret = make_user_info_map(user_info, smb_name,
|
||||
client_domain,
|
||||
remote_machine,
|
||||
get_remote_machine_name(),
|
||||
local_lm_blob,
|
||||
local_nt_blob,
|
||||
plaintext_password,
|
||||
@ -429,7 +428,7 @@ BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
|
||||
|
||||
return make_user_info_map(user_info, smb_name,
|
||||
client_domain,
|
||||
remote_machine,
|
||||
get_remote_machine_name(),
|
||||
lm_resp,
|
||||
nt_resp,
|
||||
no_plaintext_blob,
|
||||
|
@ -32,6 +32,30 @@ NSS_STATUS winbindd_request(int req_type,
|
||||
struct winbindd_request *request,
|
||||
struct winbindd_response *response);
|
||||
|
||||
NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response *response, NET_USER_INFO_3 *info3)
|
||||
{
|
||||
uint8 *info3_ndr;
|
||||
size_t len = response->length - sizeof(response);
|
||||
prs_struct ps;
|
||||
if (len > 0) {
|
||||
info3_ndr = response->extra_data;
|
||||
if (!prs_init(&ps, len, mem_ctx, UNMARSHALL)) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
prs_append_data(&ps, info3_ndr, len);
|
||||
ps.data_offset = 0;
|
||||
if (!net_io_user_info3("", info3, &ps, 1, 3)) {
|
||||
DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
prs_mem_free(&ps);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
} else {
|
||||
DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Authenticate a user with a challenge/response */
|
||||
|
||||
@ -44,11 +68,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
|
||||
struct winbindd_request request;
|
||||
struct winbindd_response response;
|
||||
NSS_STATUS result;
|
||||
struct passwd *pw;
|
||||
NTSTATUS nt_status;
|
||||
NET_USER_INFO_3 info3;
|
||||
|
||||
if (!user_info) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!auth_context) {
|
||||
@ -62,11 +86,14 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
snprintf(request.data.auth_crap.user, sizeof(request.data.auth_crap.user),
|
||||
"%s\\%s", user_info->domain.str, user_info->smb_name.str);
|
||||
request.data.auth_crap.flags = WINBIND_PAM_INFO3_NDR;
|
||||
|
||||
fstrcpy(request.data.auth_crap.user, user_info->smb_name.str);
|
||||
fstrcpy(request.data.auth_crap.domain, user_info->domain.str);
|
||||
push_utf8_fstring(request.data.auth_crap.user,
|
||||
user_info->smb_name.str);
|
||||
push_utf8_fstring(request.data.auth_crap.domain,
|
||||
user_info->domain.str);
|
||||
push_utf8_fstring(request.data.auth_crap.workstation,
|
||||
user_info->wksta_name.str);
|
||||
|
||||
memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal));
|
||||
|
||||
@ -76,27 +103,28 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
|
||||
sizeof(request.data.auth_crap.nt_resp));
|
||||
|
||||
memcpy(request.data.auth_crap.lm_resp, user_info->lm_resp.data,
|
||||
sizeof(request.data.auth_crap.lm_resp_len));
|
||||
memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data,
|
||||
request.data.auth_crap.lm_resp_len);
|
||||
memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data,
|
||||
request.data.auth_crap.nt_resp_len);
|
||||
|
||||
result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
|
||||
|
||||
if (result == NSS_STATUS_SUCCESS) {
|
||||
|
||||
pw = Get_Pwnam(user_info->internal_username.str);
|
||||
|
||||
if (pw) {
|
||||
if (make_server_info_pw(server_info, pw)) {
|
||||
nt_status = NT_STATUS_OK;
|
||||
} else {
|
||||
nt_status = NT_STATUS_NO_MEMORY;
|
||||
nt_status = NT_STATUS(response.data.auth.nt_status);
|
||||
|
||||
if (result == NSS_STATUS_SUCCESS && response.extra_data) {
|
||||
if (NT_STATUS_IS_OK(nt_status)) {
|
||||
if (NT_STATUS_IS_OK(nt_status = get_info3_from_ndr(mem_ctx, &response, &info3))) {
|
||||
nt_status =
|
||||
make_server_info_info3(mem_ctx,
|
||||
user_info->internal_username.str,
|
||||
user_info->smb_name.str,
|
||||
user_info->domain.str,
|
||||
server_info,
|
||||
&info3);
|
||||
}
|
||||
} else {
|
||||
nt_status = NT_STATUS_NO_SUCH_USER;
|
||||
}
|
||||
} else {
|
||||
nt_status = NT_STATUS_LOGON_FAILURE;
|
||||
} else if (NT_STATUS_IS_OK(nt_status)) {
|
||||
nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return nt_status;
|
||||
|
@ -492,7 +492,7 @@ static int strslashcmp(char *s1, char *s2)
|
||||
if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0;
|
||||
|
||||
/* check for s1 is an "initial" string of s2 */
|
||||
if (*s2 == '/' || *s2 == '\\') return 0;
|
||||
if ((*s2 == '/' || *s2 == '\\') && !*s1) return 0;
|
||||
|
||||
return *s1-*s2;
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
extern BOOL in_client;
|
||||
extern pstring user_socket_options;
|
||||
extern BOOL append_log;
|
||||
extern fstring remote_machine;
|
||||
|
||||
static pstring credentials;
|
||||
static pstring my_netbios_name;
|
||||
@ -377,7 +376,7 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
|
||||
}
|
||||
|
||||
/* here we are no longer interactive */
|
||||
pstrcpy(remote_machine, "smbmount"); /* sneaky ... */
|
||||
set_remote_machine_name("smbmount"); /* sneaky ... */
|
||||
setup_logging("mount.smbfs", False);
|
||||
append_log = True;
|
||||
reopen_logs();
|
||||
|
@ -282,20 +282,17 @@ smb_connect(char *workgroup, /* I - Workgroup */
|
||||
get_myname(myname);
|
||||
|
||||
nt_status = cli_full_connection(&c, myname, server, NULL, 0, share, "?????",
|
||||
username, lp_workgroup(), password, 0);
|
||||
username, workgroup, password, 0);
|
||||
|
||||
if (NT_STATUS_IS_OK(nt_status)) {
|
||||
return c;
|
||||
} else {
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
fprintf(stderr, "ERROR: Connection failed with error %s\n", nt_errstr(nt_status));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the new connection...
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return the new connection...
|
||||
*/
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
|
90
source3/configure
vendored
90
source3/configure
vendored
@ -5932,7 +5932,7 @@ else
|
||||
fi
|
||||
done
|
||||
|
||||
for ac_func in syslog vsyslog
|
||||
for ac_func in syslog vsyslog getgrouplist
|
||||
do
|
||||
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
|
||||
echo "configure:5939: checking for $ac_func" >&5
|
||||
@ -13763,6 +13763,10 @@ WINBIND_PAM_PROGS=""
|
||||
|
||||
if test x"$HAVE_WINBIND" = x"yes"; then
|
||||
echo "$ac_t""yes" 1>&6
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define WITH_WINBIND 1
|
||||
EOF
|
||||
|
||||
|
||||
WINBIND_TARGETS="bin/wbinfo"
|
||||
WINBIND_STARGETS="bin/winbindd"
|
||||
@ -13777,58 +13781,6 @@ else
|
||||
fi
|
||||
|
||||
|
||||
# Check for FreeBSD problem with getgroups
|
||||
# It returns EGID too many times in the list of groups
|
||||
# and causes a security problem
|
||||
echo $ac_n "checking whether or not getgroups returns EGID too many times""... $ac_c" 1>&6
|
||||
echo "configure:13785: checking whether or not getgroups returns EGID too many times" >&5
|
||||
if eval "test \"`echo '$''{'samba_cv_have_getgroups_too_many_egids'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
if test "$cross_compiling" = yes; then
|
||||
samba_cv_have_getgroups_too_many_egids=cross
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 13793 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
gid_t groups[10];
|
||||
int n = 10;
|
||||
|
||||
n = getgroups(n, &groups);
|
||||
/* Could actually pass back the number of EGIDs there ... */
|
||||
exit((n > 1 && groups[0] == getegid() && groups[1] == getegid()) ? 1 : 0);
|
||||
}
|
||||
EOF
|
||||
if { (eval echo configure:13809: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
then
|
||||
samba_cv_have_getgroups_too_many_egids=no
|
||||
else
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -fr conftest*
|
||||
samba_cv_have_getgroups_too_many_egids=yes
|
||||
fi
|
||||
rm -fr conftest*
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
echo "$ac_t""$samba_cv_have_getgroups_too_many_egids" 1>&6
|
||||
if test x"$samba_cv_have_getgroups_too_many_egids" = x"yes"; then
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define HAVE_GETGROUPS_TOO_MANY_EGIDS 1
|
||||
EOF
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Substitution time!
|
||||
|
||||
|
||||
@ -13848,20 +13800,20 @@ fi
|
||||
# [#include <pwd.h>])
|
||||
|
||||
echo $ac_n "checking whether struct passwd has pw_comment""... $ac_c" 1>&6
|
||||
echo "configure:13852: checking whether struct passwd has pw_comment" >&5
|
||||
echo "configure:13804: checking whether struct passwd has pw_comment" >&5
|
||||
if eval "test \"`echo '$''{'samba_cv_passwd_pw_comment'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 13858 "configure"
|
||||
#line 13810 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <pwd.h>
|
||||
int main() {
|
||||
struct passwd p; p.pw_comment;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:13865: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:13817: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
samba_cv_passwd_pw_comment=yes
|
||||
else
|
||||
@ -13886,20 +13838,20 @@ fi
|
||||
# [#include <pwd.h>])
|
||||
|
||||
echo $ac_n "checking whether struct passwd has pw_age""... $ac_c" 1>&6
|
||||
echo "configure:13890: checking whether struct passwd has pw_age" >&5
|
||||
echo "configure:13842: checking whether struct passwd has pw_age" >&5
|
||||
if eval "test \"`echo '$''{'samba_cv_passwd_pw_age'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 13896 "configure"
|
||||
#line 13848 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <pwd.h>
|
||||
int main() {
|
||||
struct passwd p; p.pw_age;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:13903: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:13855: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
samba_cv_passwd_pw_age=yes
|
||||
else
|
||||
@ -13938,7 +13890,7 @@ fi
|
||||
|
||||
if test x"$INCLUDED_POPT" != x"yes"; then
|
||||
echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6
|
||||
echo "configure:13942: checking for poptGetContext in -lpopt" >&5
|
||||
echo "configure:13894: checking for poptGetContext in -lpopt" >&5
|
||||
ac_lib_var=`echo popt'_'poptGetContext | sed 'y%./+-%__p_%'`
|
||||
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
@ -13946,7 +13898,7 @@ else
|
||||
ac_save_LIBS="$LIBS"
|
||||
LIBS="-lpopt $LIBS"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 13950 "configure"
|
||||
#line 13902 "configure"
|
||||
#include "confdefs.h"
|
||||
/* Override any gcc2 internal prototype to avoid an error. */
|
||||
/* We use char because int might match the return type of a gcc2
|
||||
@ -13957,7 +13909,7 @@ int main() {
|
||||
poptGetContext()
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:13961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:13913: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_lib_$ac_lib_var=yes"
|
||||
else
|
||||
@ -13981,9 +13933,9 @@ fi
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether to use included popt""... $ac_c" 1>&6
|
||||
echo "configure:13985: checking whether to use included popt" >&5
|
||||
echo "configure:13937: checking whether to use included popt" >&5
|
||||
if test x"$INCLUDED_POPT" = x"yes"; then
|
||||
echo "$ac_t""$srcdir/popt" 1>&6
|
||||
echo "$ac_t""yes" 1>&6
|
||||
BUILD_POPT='$(POPT_OBJS)'
|
||||
FLAGS1="-I$srcdir/popt"
|
||||
else
|
||||
@ -14004,16 +13956,16 @@ fi
|
||||
# final configure stuff
|
||||
|
||||
echo $ac_n "checking configure summary""... $ac_c" 1>&6
|
||||
echo "configure:14008: checking configure summary" >&5
|
||||
echo "configure:13960: checking configure summary" >&5
|
||||
if test "$cross_compiling" = yes; then
|
||||
echo "configure: warning: cannot run when cross-compiling" 1>&2
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 14013 "configure"
|
||||
#line 13965 "configure"
|
||||
#include "confdefs.h"
|
||||
#include "${srcdir-.}/tests/summary.c"
|
||||
EOF
|
||||
if { (eval echo configure:14017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
if { (eval echo configure:13969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
then
|
||||
echo "$ac_t""yes" 1>&6
|
||||
else
|
||||
@ -14130,7 +14082,7 @@ done
|
||||
ac_given_srcdir=$srcdir
|
||||
ac_given_INSTALL="$INSTALL"
|
||||
|
||||
trap 'rm -fr `echo "include/stamp-h Makefile script/findsmb include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
||||
trap 'rm -fr `echo "include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<EOF
|
||||
|
||||
@ -14264,7 +14216,7 @@ EOF
|
||||
|
||||
cat >> $CONFIG_STATUS <<EOF
|
||||
|
||||
CONFIG_FILES=\${CONFIG_FILES-"include/stamp-h Makefile script/findsmb"}
|
||||
CONFIG_FILES=\${CONFIG_FILES-"include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile"}
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<\EOF
|
||||
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
|
||||
|
@ -746,7 +746,7 @@ AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate
|
||||
AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64)
|
||||
AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam setlinebuf)
|
||||
AC_CHECK_FUNCS(srandom random srand rand setenv usleep strcasecmp fcvt fcvtl symlink readlink)
|
||||
AC_CHECK_FUNCS(syslog vsyslog)
|
||||
AC_CHECK_FUNCS(syslog vsyslog getgrouplist)
|
||||
# setbuffer is needed for smbtorture
|
||||
AC_CHECK_FUNCS(setbuffer)
|
||||
|
||||
@ -2695,6 +2695,7 @@ WINBIND_PAM_PROGS=""
|
||||
|
||||
if test x"$HAVE_WINBIND" = x"yes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(WITH_WINBIND)
|
||||
|
||||
WINBIND_TARGETS="bin/wbinfo"
|
||||
WINBIND_STARGETS="bin/winbindd"
|
||||
@ -2709,30 +2710,6 @@ else
|
||||
fi
|
||||
|
||||
|
||||
# Check for FreeBSD problem with getgroups
|
||||
# It returns EGID too many times in the list of groups
|
||||
# and causes a security problem
|
||||
AC_CACHE_CHECK([whether or not getgroups returns EGID too many times],
|
||||
samba_cv_have_getgroups_too_many_egids,[AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
gid_t groups[10];
|
||||
int n = 10;
|
||||
|
||||
n = getgroups(n, &groups);
|
||||
/* Could actually pass back the number of EGIDs there ... */
|
||||
exit((n > 1 && groups[0] == getegid() && groups[1] == getegid()) ? 1 : 0);
|
||||
}],
|
||||
samba_cv_have_getgroups_too_many_egids=no,samba_cv_have_getgroups_too_many_egids=yes, samba_cv_have_getgroups_too_many_egids=cross)])
|
||||
if test x"$samba_cv_have_getgroups_too_many_egids" = x"yes"; then
|
||||
AC_DEFINE(HAVE_GETGROUPS_TOO_MANY_EGIDS)
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Substitution time!
|
||||
|
||||
AC_SUBST(WINBIND_TARGETS)
|
||||
@ -2791,7 +2768,7 @@ fi
|
||||
|
||||
AC_MSG_CHECKING(whether to use included popt)
|
||||
if test x"$INCLUDED_POPT" = x"yes"; then
|
||||
AC_MSG_RESULT($srcdir/popt)
|
||||
AC_MSG_RESULT(yes)
|
||||
BUILD_POPT='$(POPT_OBJS)'
|
||||
FLAGS1="-I$srcdir/popt"
|
||||
else
|
||||
@ -2820,7 +2797,7 @@ AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"],
|
||||
builddir=`pwd`
|
||||
AC_SUBST(builddir)
|
||||
|
||||
AC_OUTPUT(include/stamp-h Makefile script/findsmb)
|
||||
AC_OUTPUT(include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile)
|
||||
|
||||
#################################################
|
||||
# Print very concise instructions on building/use
|
||||
|
@ -5,18 +5,34 @@
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
void *ld;
|
||||
char *realm;
|
||||
char *workgroup;
|
||||
char *ldap_server;
|
||||
char *ldap_server_name;
|
||||
char *kdc_server;
|
||||
void *ld; /* the active ldap structure */
|
||||
struct in_addr ldap_ip; /* the ip of the active connection, if any */
|
||||
time_t last_attempt; /* last attempt to reconnect */
|
||||
int ldap_port;
|
||||
char *bind_path;
|
||||
time_t last_attempt;
|
||||
char *password;
|
||||
char *user_name;
|
||||
char *server_realm;
|
||||
|
||||
/* info needed to find the server */
|
||||
struct {
|
||||
char *realm;
|
||||
char *workgroup;
|
||||
char *ldap_server;
|
||||
int foreign; /* set to 1 if connecting to a foreign realm */
|
||||
} server;
|
||||
|
||||
/* info needed to authenticate */
|
||||
struct {
|
||||
char *realm;
|
||||
char *password;
|
||||
char *user_name;
|
||||
char *kdc_server;
|
||||
int no_bind;
|
||||
} auth;
|
||||
|
||||
/* info derived from the servers config */
|
||||
struct {
|
||||
char *realm;
|
||||
char *bind_path;
|
||||
char *ldap_server_name;
|
||||
} config;
|
||||
} ADS_STRUCT;
|
||||
|
||||
typedef struct {
|
||||
@ -94,7 +110,7 @@ typedef void **ADS_MODLIST;
|
||||
|
||||
/* macros to simplify error returning */
|
||||
#define ADS_ERROR(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0)
|
||||
#define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc, 0)
|
||||
#define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc?rc:EINVAL, 0)
|
||||
#define ADS_ERROR_KRB5(rc) ads_build_error(ADS_ERROR_KRB5, rc, 0)
|
||||
#define ADS_ERROR_GSS(rc, minor) ads_build_error(ADS_ERROR_GSS, rc, minor)
|
||||
|
||||
@ -129,3 +145,25 @@ typedef void **ADS_MODLIST;
|
||||
/* account types */
|
||||
#define ATYPE_GROUP 0x10000000
|
||||
#define ATYPE_USER 0x30000000
|
||||
|
||||
/* Mailslot or cldap getdcname response flags */
|
||||
#define ADS_PDC 0x00000001 /* DC is PDC */
|
||||
#define ADS_GC 0x00000004 /* DC is a GC of forest */
|
||||
#define ADS_LDAP 0x00000008 /* DC is an LDAP server */
|
||||
#define ADS_DS 0x00000010 /* DC supports DS */
|
||||
#define ADS_KDC 0x00000020 /* DC is running KDC */
|
||||
#define ADS_TIMESERV 0x00000040 /* DC is running time services */
|
||||
#define ADS_CLOSEST 0x00000080 /* DC is closest to client */
|
||||
#define ADS_WRITABLE 0x00000100 /* DC has writable DS */
|
||||
#define ADS_GOOD_TIMESERV 0x00000200 /* DC has hardware clock
|
||||
(and running time) */
|
||||
#define ADS_NDNC 0x00000400 /* DomainName is non-domain NC serviced
|
||||
by LDAP server */
|
||||
#define ADS_PINGS 0x0000FFFF /* Ping response */
|
||||
#define ADS_DNS_CONTROLLER 0x20000000 /* DomainControllerName is a DNS name*/
|
||||
#define ADS_DNS_DOMAIN 0x40000000 /* DomainName is a DNS name */
|
||||
#define ADS_DNS_FOREST 0x80000000 /* DnsForestName is a DNS name */
|
||||
|
||||
/* DomainCntrollerAddressType */
|
||||
#define ADS_INET_ADDRESS 0x00000001
|
||||
#define ADS_NETBIOS_ADDRESS 0x00000002
|
||||
|
@ -285,6 +285,8 @@
|
||||
#undef _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#undef LDAP_SET_REBIND_PROC_ARGS
|
||||
|
||||
/* The number of bytes in a int. */
|
||||
#undef SIZEOF_INT
|
||||
|
||||
@ -615,6 +617,9 @@
|
||||
/* Define if you have the getgrnam function. */
|
||||
#undef HAVE_GETGRNAM
|
||||
|
||||
/* Define if you have the getgrouplist function. */
|
||||
#undef HAVE_GETGROUPLIST
|
||||
|
||||
/* Define if you have the getnetgrent function. */
|
||||
#undef HAVE_GETNETGRENT
|
||||
|
||||
@ -645,6 +650,9 @@
|
||||
/* Define if you have the innetgr function. */
|
||||
#undef HAVE_INNETGR
|
||||
|
||||
/* Define if you have the ldap_set_rebind_proc function. */
|
||||
#undef HAVE_LDAP_SET_REBIND_PROC
|
||||
|
||||
/* Define if you have the link function. */
|
||||
#undef HAVE_LINK
|
||||
|
||||
@ -873,12 +881,6 @@
|
||||
/* Define if you have the <ctype.h> header file. */
|
||||
#undef HAVE_CTYPE_H
|
||||
|
||||
/* Define if you have the <cups/cups.h> header file. */
|
||||
#undef HAVE_CUPS_CUPS_H
|
||||
|
||||
/* Define if you have the <cups/language.h> header file. */
|
||||
#undef HAVE_CUPS_LANGUAGE_H
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
@ -1125,9 +1127,6 @@
|
||||
/* Define if you have the acl library (-lacl). */
|
||||
#undef HAVE_LIBACL
|
||||
|
||||
/* Define if you have the cups library (-lcups). */
|
||||
#undef HAVE_LIBCUPS
|
||||
|
||||
/* Define if you have the gen library (-lgen). */
|
||||
#undef HAVE_LIBGEN
|
||||
|
||||
|
@ -707,9 +707,11 @@ extern int errno;
|
||||
#include "hash.h"
|
||||
#include "trans2.h"
|
||||
#include "nterr.h"
|
||||
#include "ntioctl.h"
|
||||
#include "messages.h"
|
||||
#include "charset.h"
|
||||
#include "dynconfig.h"
|
||||
#include "adt_tree.h"
|
||||
|
||||
#include "util_getent.h"
|
||||
|
||||
|
@ -187,8 +187,20 @@
|
||||
than 62*62 for the current code */
|
||||
#define MAX_SESSION_ID 3000
|
||||
|
||||
/* For the benifit of PAM and the 'session exec' scripts, we fake up a terminal
|
||||
name. This can be in one of two forms: The first for systems not using
|
||||
utmp (and therefore not constrained as to length or the need for a number
|
||||
< 3000 or so) and the second for systems with this 'well behaved terminal
|
||||
like name' constraint.
|
||||
*/
|
||||
|
||||
#ifndef SESSION_TEMPLATE
|
||||
#define SESSION_TEMPLATE "smb/%d"
|
||||
/* Paramaters are 'pid' and 'vuid' */
|
||||
#define SESSION_TEMPLATE "smb/%lu/%d"
|
||||
#endif
|
||||
|
||||
#ifndef SESSION_UTMP_TEMPLATE
|
||||
#define SESSION_UTMP_TEMPLATE "smb/%d"
|
||||
#endif
|
||||
|
||||
/* the maximum age in seconds of a password. Should be a lp_ parameter */
|
||||
|
@ -51,6 +51,7 @@
|
||||
/* #define MSG_PRINTER_NOTIFY 2001*/ /* Obsolete */
|
||||
#define MSG_PRINTER_DRVUPGRADE 2002
|
||||
#define MSG_PRINTER_NOTIFY2 2003
|
||||
#define MSG_PRINTERDATA_INIT_RESET 2004
|
||||
|
||||
/* smbd messages */
|
||||
#define MSG_SMB_CONF_UPDATED 3001
|
||||
|
@ -557,6 +557,8 @@ struct packet_struct
|
||||
#define SAMLOGON 18
|
||||
#define SAMLOGON_R 19
|
||||
#define SAMLOGON_UNK_R 21
|
||||
#define SAMLOGON_AD_UNK_R 23
|
||||
#define SAMLOGON_AD_R 25
|
||||
|
||||
/* Ids for netbios packet types. */
|
||||
|
||||
|
@ -174,14 +174,27 @@ typedef struct nt_printer_driver_info_level
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL_6 *info_6;
|
||||
} NT_PRINTER_DRIVER_INFO_LEVEL;
|
||||
|
||||
typedef struct nt_printer_param
|
||||
{
|
||||
fstring value;
|
||||
uint32 type;
|
||||
uint8 *data;
|
||||
int data_len;
|
||||
struct nt_printer_param *next;
|
||||
} NT_PRINTER_PARAM;
|
||||
/* predefined registry key names for printer data */
|
||||
|
||||
#define SPOOL_PRINTERDATA_KEY "PrinterDriverData"
|
||||
#define SPOOL_DSSPOOLER_KEY "DsSpooler"
|
||||
#define SPOOL_DSDRIVER_KEY "DsDriver"
|
||||
#define SPOOL_DSUSER_KEY "DsUser"
|
||||
#define SPOOL_PNPDATA_KEY "PnPData"
|
||||
|
||||
/* container for a single registry key */
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
REGVAL_CTR values;
|
||||
} NT_PRINTER_KEY;
|
||||
|
||||
/* container for all printer data */
|
||||
|
||||
typedef struct {
|
||||
int num_keys;
|
||||
NT_PRINTER_KEY *keys;
|
||||
} NT_PRINTER_DATA;
|
||||
|
||||
typedef struct ntdevicemode
|
||||
{
|
||||
@ -246,9 +259,8 @@ typedef struct nt_printer_info_level_2
|
||||
fstring printprocessor;
|
||||
fstring datatype;
|
||||
fstring parameters;
|
||||
NT_PRINTER_PARAM *specific;
|
||||
NT_PRINTER_DATA data;
|
||||
SEC_DESC_BUF *secdesc_buf;
|
||||
/* not used but ... and how ??? */
|
||||
uint32 changeid;
|
||||
uint32 c_setprinter;
|
||||
uint32 setuptime;
|
||||
|
@ -57,7 +57,7 @@ typedef struct pdb_context
|
||||
|
||||
BOOL (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username);
|
||||
|
||||
BOOL (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, DOM_SID *sid);
|
||||
BOOL (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid);
|
||||
|
||||
BOOL (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
|
||||
|
||||
@ -88,7 +88,7 @@ typedef struct pdb_methods
|
||||
|
||||
BOOL (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username);
|
||||
|
||||
BOOL (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, DOM_SID *Sid);
|
||||
BOOL (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const DOM_SID *Sid);
|
||||
|
||||
BOOL (*add_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass);
|
||||
|
||||
|
@ -73,6 +73,7 @@
|
||||
#define LSA_RETRPRIVDATA 0x2b
|
||||
#define LSA_OPENPOLICY2 0x2c
|
||||
#define LSA_UNK_GET_CONNUSER 0x2d /* LsaGetConnectedCredentials ? */
|
||||
#define LSA_QUERYINFO2 0x2e
|
||||
|
||||
/* XXXX these are here to get a compile! */
|
||||
#define LSA_LOOKUPRIDS 0xFD
|
||||
@ -261,6 +262,43 @@ typedef struct lsa_r_query_info
|
||||
|
||||
} LSA_R_QUERY_INFO;
|
||||
|
||||
/* LSA_DNS_DOM_INFO - DNS domain info - info class 12*/
|
||||
typedef struct lsa_dns_dom_info
|
||||
{
|
||||
UNIHDR hdr_nb_dom_name; /* netbios domain name */
|
||||
UNIHDR hdr_dns_dom_name;
|
||||
UNIHDR hdr_forest_name;
|
||||
|
||||
GUID dom_guid; /* domain GUID */
|
||||
|
||||
UNISTR2 uni_nb_dom_name;
|
||||
UNISTR2 uni_dns_dom_name;
|
||||
UNISTR2 uni_forest_name;
|
||||
|
||||
uint32 ptr_dom_sid;
|
||||
DOM_SID2 dom_sid; /* domain SID */
|
||||
} LSA_DNS_DOM_INFO;
|
||||
|
||||
typedef union lsa_info2_union
|
||||
{
|
||||
LSA_DNS_DOM_INFO dns_dom_info;
|
||||
} LSA_INFO2_UNION;
|
||||
|
||||
/* LSA_Q_QUERY_INFO2 - LSA query info */
|
||||
typedef struct lsa_q_query_info2
|
||||
{
|
||||
POLICY_HND pol; /* policy handle */
|
||||
uint16 info_class; /* info class */
|
||||
} LSA_Q_QUERY_INFO2;
|
||||
|
||||
typedef struct lsa_r_query_info2
|
||||
{
|
||||
uint32 ptr; /* pointer to info struct */
|
||||
uint16 info_class;
|
||||
LSA_INFO2_UNION info; /* so far the only one */
|
||||
NTSTATUS status;
|
||||
} LSA_R_QUERY_INFO2;
|
||||
|
||||
/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
|
||||
typedef struct lsa_enum_trust_dom_info
|
||||
{
|
||||
|
@ -1,9 +1,10 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
SMB parameters and setup
|
||||
Copyright (C) Andrew Tridgell 1992-1997
|
||||
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
|
||||
Copyright (C) Paul Ashton 1997
|
||||
Copyright (C) Andrew Tridgell 1992-1997.
|
||||
Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
|
||||
Copyright (C) Paul Ashton 1997.
|
||||
Copyright (C) Gerald Carter 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
|
||||
@ -26,35 +27,35 @@
|
||||
|
||||
/* winreg pipe defines
|
||||
NOT IMPLEMENTED !!
|
||||
#define REG_OPEN_HKCR 0x00
|
||||
#define _REG_UNK_01 0x01
|
||||
#define _REG_UNK_03 0x03
|
||||
#define REG_CREATE_KEY 0x06
|
||||
#define REG_DELETE_KEY 0x07
|
||||
#define REG_DELETE_VALUE 0x08
|
||||
#define REG_ENUM_VALUE 0x0a
|
||||
#define REG_FLUSH_KEY 0x0b
|
||||
#define REG_GET_KEY_SEC 0x0c
|
||||
#define _REG_UNK_0D 0x0d
|
||||
#define _REG_UNK_0E 0x0e
|
||||
#define _REG_UNK_12 0x12
|
||||
#define _REG_UNK_13 0x13
|
||||
#define _REG_UNK_14 0x14
|
||||
#define REG_SET_KEY_SEC 0x15
|
||||
#define REG_CREATE_VALUE 0x16
|
||||
#define _REG_UNK_17 0x17
|
||||
*/
|
||||
|
||||
/* Implemented */
|
||||
#define REG_OPEN_HKCR 0x00
|
||||
#define REG_OPEN_HKLM 0x02
|
||||
#define REG_OPEN_HKU 0x04
|
||||
#define REG_CLOSE 0x05
|
||||
#define REG_ENUM_KEY 0x09
|
||||
#define REG_ENUM_VALUE 0x0a
|
||||
#define REG_OPEN_ENTRY 0x0f
|
||||
#define REG_QUERY_KEY 0x10
|
||||
#define REG_INFO 0x11
|
||||
#define REG_SHUTDOWN 0x18
|
||||
#define REG_ABORT_SHUTDOWN 0x19
|
||||
#define REG_SAVE_KEY 0x14 /* no idea what the real name is */
|
||||
#define REG_UNKNOWN_1A 0x1a
|
||||
|
||||
|
||||
@ -63,6 +64,12 @@
|
||||
#define HKEY_LOCAL_MACHINE 0x80000002
|
||||
#define HKEY_USERS 0x80000003
|
||||
|
||||
#define KEY_HKLM "HKLM"
|
||||
#define KEY_HKU "HKU"
|
||||
#define KEY_HKCR "HKCR"
|
||||
#define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print"
|
||||
#define KEY_TREE_ROOT ""
|
||||
|
||||
/* Registry data types */
|
||||
|
||||
#define REG_NONE 0
|
||||
@ -82,6 +89,65 @@
|
||||
#define REG_FORCE_SHUTDOWN 0x001
|
||||
#define REG_REBOOT_ON_SHUTDOWN 0x100
|
||||
|
||||
/* structure to contain registry values */
|
||||
|
||||
typedef struct {
|
||||
fstring valuename;
|
||||
uint16 type;
|
||||
uint32 size; /* in bytes */
|
||||
uint8 *data_p;
|
||||
} REGISTRY_VALUE;
|
||||
|
||||
/* container for regostry values */
|
||||
|
||||
typedef struct {
|
||||
TALLOC_CTX *ctx;
|
||||
uint32 num_values;
|
||||
REGISTRY_VALUE **values;
|
||||
} REGVAL_CTR;
|
||||
|
||||
/* container for registry subkey names */
|
||||
|
||||
typedef struct {
|
||||
TALLOC_CTX *ctx;
|
||||
uint32 num_subkeys;
|
||||
char **subkeys;
|
||||
} REGSUBKEY_CTR;
|
||||
|
||||
|
||||
/*
|
||||
* container for function pointers to enumeration routines
|
||||
* for vitural registry view
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* functions for enumerating subkeys and values */
|
||||
int (*subkey_fn)( char *key, REGSUBKEY_CTR *subkeys);
|
||||
int (*value_fn) ( char *key, REGVAL_CTR *val );
|
||||
BOOL (*store_subkeys_fn)( char *key, REGSUBKEY_CTR *subkeys );
|
||||
BOOL (*store_values_fn)( char *key, REGVAL_CTR *val );
|
||||
} REGISTRY_OPS;
|
||||
|
||||
typedef struct {
|
||||
char *keyname; /* full path to name of key */
|
||||
REGISTRY_OPS *ops; /* registry function hooks */
|
||||
} REGISTRY_HOOK;
|
||||
|
||||
|
||||
|
||||
/* structure to store the registry handles */
|
||||
|
||||
typedef struct _RegistryKey {
|
||||
|
||||
struct _RegistryKey *prev, *next;
|
||||
|
||||
POLICY_HND hnd;
|
||||
pstring name; /* full name of registry key */
|
||||
REGISTRY_HOOK *hook;
|
||||
|
||||
} REGISTRY_KEY;
|
||||
|
||||
|
||||
/* REG_Q_OPEN_HKCR */
|
||||
typedef struct q_reg_open_hkcr_info
|
||||
{
|
||||
@ -107,7 +173,7 @@ typedef struct q_reg_open_hklm_info
|
||||
uint32 ptr;
|
||||
uint16 unknown_0; /* 0xE084 - 16 bit unknown */
|
||||
uint16 unknown_1; /* random. changes */
|
||||
uint32 access_mask; /* 0x0000 0002 - 32 bit unknown */
|
||||
uint32 access_mask;
|
||||
|
||||
}
|
||||
REG_Q_OPEN_HKLM;
|
||||
@ -246,6 +312,7 @@ typedef struct q_reg_query_value_info
|
||||
uint32 ptr2; /* pointer */
|
||||
uint32 len_value2; /* */
|
||||
|
||||
|
||||
} REG_Q_ENUM_VALUE;
|
||||
|
||||
/* REG_R_ENUM_VALUE */
|
||||
@ -258,7 +325,7 @@ typedef struct r_reg_enum_value_info
|
||||
uint32 type; /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
|
||||
|
||||
uint32 ptr_value; /* pointer */
|
||||
BUFFER2 *buf_value; /* value, in byte buffer */
|
||||
BUFFER2 buf_value; /* value, in byte buffer */
|
||||
|
||||
uint32 ptr1; /* pointer */
|
||||
uint32 len_value1; /* */
|
||||
@ -388,6 +455,29 @@ typedef struct r_reg_unk_1a_info
|
||||
} REG_R_UNKNOWN_1A;
|
||||
|
||||
|
||||
/* REG_Q_UNKNOWN_1A */
|
||||
typedef struct q_reg_unknown_14
|
||||
{
|
||||
POLICY_HND pol; /* policy handle */
|
||||
|
||||
UNIHDR hdr_file; /* unicode product type header */
|
||||
UNISTR2 uni_file; /* local filename to save key as from regedt32.exe */
|
||||
/* e.g. "c:\temp\test.dat" */
|
||||
|
||||
uint32 unknown; /* 0x0000 0000 */
|
||||
|
||||
} REG_Q_SAVE_KEY;
|
||||
|
||||
|
||||
/* REG_R_UNKNOWN_1A */
|
||||
typedef struct r_reg_unknown_14
|
||||
{
|
||||
NTSTATUS status; /* return status */
|
||||
|
||||
} REG_R_SAVE_KEY;
|
||||
|
||||
|
||||
|
||||
/* REG_Q_CLOSE */
|
||||
typedef struct reg_q_close_info
|
||||
{
|
||||
@ -481,7 +571,7 @@ typedef struct r_reg_info_info
|
||||
uint32 type; /* key datatype */
|
||||
|
||||
uint32 ptr_uni_val; /* key value pointer */
|
||||
BUFFER2 *uni_val; /* key value */
|
||||
BUFFER2 uni_val; /* key value */
|
||||
|
||||
uint32 ptr_max_len;
|
||||
uint32 buf_max_len;
|
||||
|
@ -4,7 +4,10 @@
|
||||
Copyright (C) Andrew Tridgell 1992-2000
|
||||
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
|
||||
Copyright (C) Paul Ashton 1997-2000
|
||||
Copyright (C) Jean François Micouleau 1998-2001.
|
||||
Copyright (C) Jean François Micouleau 1998-2001
|
||||
Copyright (C) Anthony Liguori 2002
|
||||
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
|
||||
@ -24,10 +27,8 @@
|
||||
#ifndef _RPC_SAMR_H /* _RPC_SAMR_H */
|
||||
#define _RPC_SAMR_H
|
||||
|
||||
|
||||
#include "rpc_misc.h"
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
the following information comes from a QuickView on samsrv.dll,
|
||||
and gives an idea of exactly what is needed:
|
||||
@ -144,6 +145,7 @@ SamrTestPrivateFunctionsUser
|
||||
#define SAMR_GET_DOM_PWINFO 0x38
|
||||
#define SAMR_CONNECT 0x39
|
||||
#define SAMR_SET_USERINFO 0x3A
|
||||
#define SAMR_CONNECT4 0x3E
|
||||
|
||||
/* Access bits to the SAM-object */
|
||||
|
||||
@ -176,17 +178,17 @@ SamrTestPrivateFunctionsUser
|
||||
|
||||
/* Access bits to Domain-objects */
|
||||
|
||||
#define DOMAIN_ACCESS_LOOKUP_INFO_1 0x000000001
|
||||
#define DOMAIN_ACCESS_SET_INFO_1 0x000000002
|
||||
#define DOMAIN_ACCESS_LOOKUP_INFO_2 0x000000004
|
||||
#define DOMAIN_ACCESS_SET_INFO_2 0x000000008
|
||||
#define DOMAIN_ACCESS_CREATE_USER 0x000000010
|
||||
#define DOMAIN_ACCESS_CREATE_GROUP 0x000000020
|
||||
#define DOMAIN_ACCESS_CREATE_ALIAS 0x000000040
|
||||
#define DOMAIN_ACCESS_UNKNOWN_80 0x000000080
|
||||
#define DOMAIN_ACCESS_ENUM_ACCOUNTS 0x000000100
|
||||
#define DOMAIN_ACCESS_OPEN_ACCOUNT 0x000000200
|
||||
#define DOMAIN_ACCESS_SET_INFO_3 0x000000400
|
||||
#define DOMAIN_ACCESS_LOOKUP_INFO_1 0x00000001
|
||||
#define DOMAIN_ACCESS_SET_INFO_1 0x00000002
|
||||
#define DOMAIN_ACCESS_LOOKUP_INFO_2 0x00000004
|
||||
#define DOMAIN_ACCESS_SET_INFO_2 0x00000008
|
||||
#define DOMAIN_ACCESS_CREATE_USER 0x00000010
|
||||
#define DOMAIN_ACCESS_CREATE_GROUP 0x00000020
|
||||
#define DOMAIN_ACCESS_CREATE_ALIAS 0x00000040
|
||||
#define DOMAIN_ACCESS_UNKNOWN_80 0x00000080
|
||||
#define DOMAIN_ACCESS_ENUM_ACCOUNTS 0x00000100
|
||||
#define DOMAIN_ACCESS_OPEN_ACCOUNT 0x00000200
|
||||
#define DOMAIN_ACCESS_SET_INFO_3 0x00000400
|
||||
|
||||
#define DOMAIN_ALL_ACCESS ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
|
||||
DOMAIN_ACCESS_SET_INFO_3 | \
|
||||
@ -220,17 +222,17 @@ SamrTestPrivateFunctionsUser
|
||||
|
||||
/* Access bits to User-objects */
|
||||
|
||||
#define USER_ACCESS_GET_NAME_ETC 0x000000001
|
||||
#define USER_ACCESS_GET_LOCALE 0x000000002
|
||||
#define USER_ACCESS_SET_LOC_COM 0x000000004
|
||||
#define USER_ACCESS_GET_LOGONINFO 0x000000008
|
||||
#define USER_ACCESS_UNKNOWN_10 0x000000010
|
||||
#define USER_ACCESS_SET_ATTRIBUTES 0x000000020
|
||||
#define USER_ACCESS_CHANGE_PASSWORD 0x000000040
|
||||
#define USER_ACCESS_SET_PASSWORD 0x000000080
|
||||
#define USER_ACCESS_GET_GROUPS 0x000000100
|
||||
#define USER_ACCESS_UNKNOWN_200 0x000000200
|
||||
#define USER_ACCESS_UNKNOWN_400 0x000000400
|
||||
#define USER_ACCESS_GET_NAME_ETC 0x00000001
|
||||
#define USER_ACCESS_GET_LOCALE 0x00000002
|
||||
#define USER_ACCESS_SET_LOC_COM 0x00000004
|
||||
#define USER_ACCESS_GET_LOGONINFO 0x00000008
|
||||
#define USER_ACCESS_UNKNOWN_10 0x00000010
|
||||
#define USER_ACCESS_SET_ATTRIBUTES 0x00000020
|
||||
#define USER_ACCESS_CHANGE_PASSWORD 0x00000040
|
||||
#define USER_ACCESS_SET_PASSWORD 0x00000080
|
||||
#define USER_ACCESS_GET_GROUPS 0x00000100
|
||||
#define USER_ACCESS_UNKNOWN_200 0x00000200
|
||||
#define USER_ACCESS_UNKNOWN_400 0x00000400
|
||||
|
||||
#define USER_ALL_ACCESS ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
|
||||
USER_ACCESS_UNKNOWN_400 | \
|
||||
@ -312,9 +314,6 @@ SamrTestPrivateFunctionsUser
|
||||
#define ALIAS_EXECUTE ( STANDARD_RIGHTS_EXECUTE_ACCESS | \
|
||||
ALIAS_ACCESS_LOOKUP_INFO )
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct _DISP_USER_INFO {
|
||||
SAM_ACCOUNT *sam;
|
||||
} DISP_USER_INFO;
|
||||
@ -1647,7 +1646,7 @@ typedef struct r_samr_create_user_info
|
||||
{
|
||||
POLICY_HND user_pol; /* policy handle associated with user */
|
||||
|
||||
uint32 unknown_0; /* 0x0007 03ff */
|
||||
uint32 access_granted;
|
||||
uint32 user_rid; /* user RID */
|
||||
NTSTATUS status; /* return status */
|
||||
|
||||
@ -1870,6 +1869,19 @@ typedef struct r_samr_connect_info
|
||||
|
||||
} SAMR_R_CONNECT;
|
||||
|
||||
/* SAMR_Q_CONNECT4 */
|
||||
typedef struct q_samr_connect4_info
|
||||
{
|
||||
uint32 ptr_srv_name; /* pointer to server name */
|
||||
UNISTR2 uni_srv_name;
|
||||
|
||||
uint32 unk_0; /* possible server name type, 1 for IP num, 2 for name */
|
||||
uint32 access_mask;
|
||||
} SAMR_Q_CONNECT4;
|
||||
|
||||
/* SAMR_R_CONNECT4 - same format as connect */
|
||||
typedef struct r_samr_connect_info SAMR_R_CONNECT4;
|
||||
|
||||
/* SAMR_Q_GET_DOM_PWINFO */
|
||||
typedef struct q_samr_get_dom_pwinfo
|
||||
{
|
||||
@ -2008,6 +2020,4 @@ typedef struct r_samr_set_domain_info
|
||||
|
||||
} SAMR_R_SET_DOMAIN_INFO;
|
||||
|
||||
|
||||
#endif /* _RPC_SAMR_H */
|
||||
|
||||
|
@ -202,6 +202,7 @@
|
||||
#define NOTIFY_TWO_VALUE 2 /* Notify data is stored in value2 */
|
||||
#define NOTIFY_POINTER 3 /* Data is a pointer to a buffer */
|
||||
#define NOTIFY_STRING 4 /* Data is a pointer to a buffer w/length */
|
||||
#define NOTIFY_SECDESC 5 /* Data is a security descriptor */
|
||||
|
||||
#define PRINTER_NOTIFY_TYPE 0x00
|
||||
#define JOB_NOTIFY_TYPE 0x01
|
||||
@ -801,15 +802,16 @@ typedef struct spool_notify_info_data
|
||||
uint16 field;
|
||||
uint32 reserved;
|
||||
uint32 id;
|
||||
union
|
||||
{
|
||||
union {
|
||||
uint32 value[2];
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
uint32 length;
|
||||
uint16 *string;
|
||||
}
|
||||
data;
|
||||
} data;
|
||||
struct {
|
||||
uint32 size;
|
||||
SEC_DESC *desc;
|
||||
} sd;
|
||||
}
|
||||
notify_data;
|
||||
uint32 size;
|
||||
|
@ -4,6 +4,7 @@
|
||||
Copyright (C) Andrew Tridgell 1992-1997
|
||||
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
|
||||
Copyright (C) Paul Ashton 1997
|
||||
Copyright (C) Nigel Williams 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
|
||||
@ -33,6 +34,7 @@
|
||||
#define SRV_NET_SHARE_GET_INFO 0x10
|
||||
#define SRV_NET_SHARE_SET_INFO 0x11
|
||||
#define SRV_NET_SHARE_DEL 0x12
|
||||
#define SRV_NET_SHARE_DEL_STICKY 0x13
|
||||
#define SRV_NET_SRV_GET_INFO 0x15
|
||||
#define SRV_NET_SRV_SET_INFO 0x16
|
||||
#define SRV_NET_DISK_ENUM 0x17
|
||||
@ -54,7 +56,7 @@ typedef struct disk_enum_container {
|
||||
uint32 entries_read;
|
||||
uint32 unknown;
|
||||
uint32 disk_info_ptr;
|
||||
DISK_INFO disk_info[MAX_SERVER_DISK_ENTRIES];
|
||||
DISK_INFO *disk_info;
|
||||
} DISK_ENUM_CONTAINER;
|
||||
|
||||
typedef struct net_srv_disk_enum {
|
||||
@ -294,6 +296,29 @@ typedef struct r_net_conn_enum_info
|
||||
|
||||
} SRV_R_NET_CONN_ENUM;
|
||||
|
||||
/* SH_INFO_0 */
|
||||
typedef struct ptr_share_info0
|
||||
{
|
||||
uint32 ptr_netname; /* pointer to net name. */
|
||||
} SH_INFO_0;
|
||||
|
||||
/* SH_INFO_0_STR (level 0 share info strings) */
|
||||
typedef struct str_share_info0
|
||||
{
|
||||
SH_INFO_0 *ptrs;
|
||||
|
||||
UNISTR2 uni_netname; /* unicode string of net name */
|
||||
|
||||
} SH_INFO_0_STR;
|
||||
|
||||
/* SRV_SHARE_INFO_0 */
|
||||
typedef struct share_info_0_info
|
||||
{
|
||||
SH_INFO_0 info_0;
|
||||
SH_INFO_0_STR info_0_str;
|
||||
|
||||
} SRV_SHARE_INFO_0;
|
||||
|
||||
/* SH_INFO_1 (pointers to level 1 share info strings) */
|
||||
typedef struct ptr_share_info1
|
||||
{
|
||||
@ -306,6 +331,8 @@ typedef struct ptr_share_info1
|
||||
/* SH_INFO_1_STR (level 1 share info strings) */
|
||||
typedef struct str_share_info1
|
||||
{
|
||||
SH_INFO_1 *ptrs;
|
||||
|
||||
UNISTR2 uni_netname; /* unicode string of net name */
|
||||
UNISTR2 uni_remark; /* unicode string of comment */
|
||||
|
||||
@ -336,6 +363,8 @@ typedef struct ptr_share_info2
|
||||
/* SH_INFO_2_STR (level 2 share info strings) */
|
||||
typedef struct str_share_info2
|
||||
{
|
||||
SH_INFO_2 *ptrs;
|
||||
|
||||
UNISTR2 uni_netname; /* unicode string of net name (e.g NETLOGON) */
|
||||
UNISTR2 uni_remark; /* unicode string of comment (e.g "Logon server share") */
|
||||
UNISTR2 uni_path; /* unicode string of local path (e.g c:\winnt\system32\repl\import\scripts) */
|
||||
@ -383,6 +412,8 @@ typedef struct ptr_share_info502
|
||||
uint32 num_uses; /* current uses */
|
||||
uint32 ptr_path; /* pointer to path name */
|
||||
uint32 ptr_passwd; /* pointer to password */
|
||||
uint32 reserved; /* this holds the space taken by the sd in the rpc packet */
|
||||
uint32 reserved_offset; /* required for _post operation when marshalling */
|
||||
uint32 sd_size; /* size of security descriptor */
|
||||
uint32 ptr_sd; /* pointer to security descriptor */
|
||||
|
||||
@ -398,6 +429,7 @@ typedef struct str_share_info502
|
||||
UNISTR2 uni_path; /* unicode string of local path (e.g c:\winnt\system32\repl\import\scripts) */
|
||||
UNISTR2 uni_passwd; /* unicode string of password - presumably for share level security (e.g NULL) */
|
||||
|
||||
uint32 reserved;
|
||||
uint32 sd_size;
|
||||
SEC_DESC *sd;
|
||||
|
||||
@ -411,12 +443,57 @@ typedef struct share_info_502_info
|
||||
|
||||
} SRV_SHARE_INFO_502;
|
||||
|
||||
/* SRV_SHARE_INFO_1005 */
|
||||
typedef struct ptr_share_info1004
|
||||
{
|
||||
uint32 ptr_remark;
|
||||
|
||||
} SH_INFO_1004;
|
||||
|
||||
typedef struct str_share_info1004
|
||||
{
|
||||
SH_INFO_1004 *ptrs;
|
||||
|
||||
UNISTR2 uni_remark;
|
||||
|
||||
} SH_INFO_1004_STR;
|
||||
|
||||
typedef struct ptr_info_1004_info
|
||||
{
|
||||
SH_INFO_1004 info_1004;
|
||||
SH_INFO_1004_STR info_1004_str;
|
||||
} SRV_SHARE_INFO_1004;
|
||||
|
||||
typedef struct share_info_1005_info
|
||||
{
|
||||
uint32 dfs_root_flag;
|
||||
} SRV_SHARE_INFO_1005;
|
||||
|
||||
typedef struct share_info_1006_info
|
||||
{
|
||||
uint32 max_uses;
|
||||
} SRV_SHARE_INFO_1006;
|
||||
|
||||
typedef struct ptr_share_info1007
|
||||
{
|
||||
uint32 flags;
|
||||
uint32 ptr_AlternateDirectoryName;
|
||||
|
||||
} SH_INFO_1007;
|
||||
|
||||
typedef struct str_share_info1007
|
||||
{
|
||||
SH_INFO_1007 *ptrs;
|
||||
|
||||
UNISTR2 uni_AlternateDirectoryName;
|
||||
|
||||
} SH_INFO_1007_STR;
|
||||
|
||||
typedef struct ptr_info_1007_info
|
||||
{
|
||||
SH_INFO_1007 info_1007;
|
||||
SH_INFO_1007_STR info_1007_str;
|
||||
} SRV_SHARE_INFO_1007;
|
||||
|
||||
/* SRV_SHARE_INFO_1501 */
|
||||
typedef struct share_info_1501_info
|
||||
{
|
||||
@ -435,10 +512,16 @@ typedef struct srv_share_info_ctr_info
|
||||
uint32 num_entries2;
|
||||
|
||||
union {
|
||||
SRV_SHARE_INFO_1 *info1; /* share info level 1 */
|
||||
SRV_SHARE_INFO_2 *info2; /* share info level 2 */
|
||||
SRV_SHARE_INFO_501 *info501; /* share info level 501 */
|
||||
SRV_SHARE_INFO_502 *info502; /* share info level 502 */
|
||||
SRV_SHARE_INFO_0 *info0;
|
||||
SRV_SHARE_INFO_1 *info1; /* share info level 1 */
|
||||
SRV_SHARE_INFO_2 *info2; /* share info level 2 */
|
||||
SRV_SHARE_INFO_501 *info501; /* share info level 501 */
|
||||
SRV_SHARE_INFO_502 *info502; /* share info level 502 */
|
||||
SRV_SHARE_INFO_1004 *info1004;
|
||||
SRV_SHARE_INFO_1005 *info1005;
|
||||
SRV_SHARE_INFO_1006 *info1006;
|
||||
SRV_SHARE_INFO_1007 *info1007;
|
||||
SRV_SHARE_INFO_1501 *info1501;
|
||||
void *info;
|
||||
|
||||
} share;
|
||||
@ -484,19 +567,21 @@ typedef struct q_net_share_get_info_info
|
||||
|
||||
} SRV_Q_NET_SHARE_GET_INFO;
|
||||
|
||||
/* JRA. NB. We also need level 1004 and 1006 here. */
|
||||
|
||||
/* SRV_SHARE_INFO */
|
||||
typedef struct srv_share_info {
|
||||
uint32 switch_value;
|
||||
uint32 ptr_share_ctr;
|
||||
|
||||
union {
|
||||
SRV_SHARE_INFO_0 info0;
|
||||
SRV_SHARE_INFO_1 info1;
|
||||
SRV_SHARE_INFO_2 info2;
|
||||
SRV_SHARE_INFO_501 info501;
|
||||
SRV_SHARE_INFO_502 info502;
|
||||
SRV_SHARE_INFO_1004 info1004;
|
||||
SRV_SHARE_INFO_1005 info1005;
|
||||
SRV_SHARE_INFO_1006 info1006;
|
||||
SRV_SHARE_INFO_1007 info1007;
|
||||
SRV_SHARE_INFO_1501 info1501;
|
||||
} share;
|
||||
} SRV_SHARE_INFO;
|
||||
@ -520,12 +605,16 @@ typedef struct q_net_share_set_info_info
|
||||
|
||||
SRV_SHARE_INFO info;
|
||||
|
||||
uint32 ptr_parm_error;
|
||||
uint32 parm_error;
|
||||
|
||||
} SRV_Q_NET_SHARE_SET_INFO;
|
||||
|
||||
/* SRV_R_NET_SHARE_SET_INFO */
|
||||
typedef struct r_net_share_set_info
|
||||
{
|
||||
uint32 switch_value; /* switch value */
|
||||
uint32 ptr_parm_error;
|
||||
uint32 parm_error;
|
||||
|
||||
WERROR status; /* return status */
|
||||
|
||||
@ -549,7 +638,9 @@ typedef struct q_net_share_add
|
||||
/* SRV_R_NET_SHARE_ADD */
|
||||
typedef struct r_net_share_add
|
||||
{
|
||||
uint32 switch_value; /* switch value */
|
||||
|
||||
uint32 ptr_parm_error;
|
||||
uint32 parm_error;
|
||||
|
||||
WERROR status; /* return status */
|
||||
|
||||
@ -594,9 +685,12 @@ typedef struct str_file_info3_info
|
||||
/* SRV_FILE_INFO_3 */
|
||||
typedef struct srv_file_info_3
|
||||
{
|
||||
uint32 num_entries_read; /* EntriesRead */
|
||||
uint32 ptr_file_info; /* Buffer */
|
||||
|
||||
uint32 num_entries_read2; /* EntriesRead */
|
||||
FILE_INFO_3 info_3; /* file entry details */
|
||||
FILE_INFO_3_STR info_3_str; /* file entry strings */
|
||||
|
||||
} SRV_FILE_INFO_3;
|
||||
|
||||
/* SRV_FILE_INFO_CTR */
|
||||
|
@ -35,6 +35,10 @@
|
||||
#define SECRETS_DOMAIN_SID "SECRETS/SID"
|
||||
#define SECRETS_SAM_SID "SAM/SID"
|
||||
|
||||
/* The domain GUID and server GUID (NOT the same) are also not secret */
|
||||
#define SECRETS_DOMAIN_GUID "SECRETS/DOMGUID"
|
||||
#define SECRETS_SERVER_GUID "SECRETS/GUID"
|
||||
|
||||
#define SECRETS_LDAP_BIND_PW "SECRETS/LDAP_BIND_PW"
|
||||
|
||||
/* Authenticated user info is stored in secrets.tdb under these keys */
|
||||
|
@ -38,7 +38,9 @@
|
||||
|
||||
#define NMB_PORT 137
|
||||
#define DGRAM_PORT 138
|
||||
#define SMB_PORT 139
|
||||
#define SMB_PORT1 445
|
||||
#define SMB_PORT2 139
|
||||
#define SMB_PORTS "445 139"
|
||||
|
||||
#define False (0)
|
||||
#define True (1)
|
||||
@ -383,7 +385,7 @@ typedef struct files_struct
|
||||
int fnum;
|
||||
struct connection_struct *conn;
|
||||
int fd;
|
||||
int print_jobid;
|
||||
uint32 print_jobid;
|
||||
SMB_DEV_T dev;
|
||||
SMB_INO_T inode;
|
||||
BOOL delete_on_close;
|
||||
@ -444,6 +446,15 @@ typedef struct
|
||||
#include "smb_acls.h"
|
||||
#include "vfs.h"
|
||||
|
||||
typedef struct smb_vfs_handle_struct
|
||||
{
|
||||
void *data;
|
||||
/* Handle on dlopen() call */
|
||||
void *handle;
|
||||
struct smb_vfs_handle_struct *next, *prev;
|
||||
|
||||
} smb_vfs_handle_struct;
|
||||
|
||||
typedef struct connection_struct
|
||||
{
|
||||
struct connection_struct *next, *prev;
|
||||
@ -461,9 +472,7 @@ typedef struct connection_struct
|
||||
char *origpath;
|
||||
|
||||
struct vfs_ops vfs_ops; /* Filesystem operations */
|
||||
/* Handle on dlopen() call */
|
||||
void *dl_handle;
|
||||
void *vfs_private;
|
||||
struct smb_vfs_handle_struct *vfs_private;
|
||||
|
||||
char *user; /* name of user who *opened* this connection */
|
||||
uid_t uid; /* uid of user who *opened* this connection */
|
||||
@ -1594,8 +1603,8 @@ typedef struct user_struct
|
||||
|
||||
uint8 session_key[16];
|
||||
|
||||
int session_id; /* used by utmp and pam session code */
|
||||
|
||||
char *session_keystr; /* used by utmp and pam session code.
|
||||
TDB key string */
|
||||
int homes_snum;
|
||||
|
||||
} user_struct;
|
||||
@ -1667,4 +1676,8 @@ typedef struct {
|
||||
|
||||
#define DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH 14
|
||||
|
||||
/* Common popt structures */
|
||||
|
||||
extern struct poptOption popt_common_debug[];
|
||||
|
||||
#endif /* _SMB_H */
|
||||
|
@ -1 +1 @@
|
||||
#define VERSION "3.0-alpha17"
|
||||
#define VERSION "3.0-alpha18"
|
||||
|
@ -1,7 +1,8 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
VFS structures and parameters
|
||||
Copyright (C) Tim Potter 1999
|
||||
Copyright (C) Tim Potter 1999
|
||||
Copyright (C) Alexander Bokovoy 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
|
||||
@ -16,6 +17,8 @@
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef _VFS_H
|
||||
@ -40,7 +43,48 @@
|
||||
|
||||
/* Changed to version 2 for CIFS UNIX extensions (mknod and link added). JRA. */
|
||||
/* Changed to version 3 for POSIX acl extensions. JRA. */
|
||||
#define SMB_VFS_INTERFACE_VERSION 3
|
||||
/* Changed to version 4 for cascaded VFS interface. Alexander Bokovoy. */
|
||||
#define SMB_VFS_INTERFACE_VERSION 5
|
||||
|
||||
|
||||
/* Version of supported cascaded interface backward copmatibility.
|
||||
(version 4 corresponds to SMB_VFS_INTERFACE_VERSION 4)
|
||||
It is used in vfs_init_custom() to detect VFS modules which conform to cascaded
|
||||
VFS interface but implement elder version than current version of Samba uses.
|
||||
This allows to use old modules with new VFS interface as far as combined VFS operation
|
||||
set is coherent (will be in most cases).
|
||||
*/
|
||||
#define SMB_VFS_INTERFACE_CASCADED 4
|
||||
|
||||
/*
|
||||
Each VFS module must provide following global functions:
|
||||
vfs_init -- initialization function
|
||||
vfs_done -- finalization function
|
||||
|
||||
vfs_init must return proper initialized vfs_op_tuple[] array
|
||||
which describes all operations this module claims to intercept. This function
|
||||
is called whenever module is loaded into smbd process using sys_dlopen().
|
||||
|
||||
vfs_init must store somewhere vfs_handle reference if module wants to store per-instance
|
||||
private information for further usage. vfs_handle->data should be used to
|
||||
store such information. Do not try to change other fields in this structure
|
||||
or results likely to be unpredictable.
|
||||
|
||||
vfs_done must perform finalization of the module. In particular,
|
||||
this function must free vfs_ops structure returned to module from smb_vfs_get_opaque_ops()
|
||||
function if it is used (see below). This function is called whenever module
|
||||
is unloaded from smbd process using sys_dlclose().
|
||||
|
||||
Prototypes:
|
||||
vfs_op_tuple *vfs_init(int *vfs_version, const struct vfs_ops *def_vfs_ops,
|
||||
struct smb_vfs_handle_struct *vfs_handle);
|
||||
void vfs_done(connection_struct *conn);
|
||||
|
||||
All intercepted VFS operations must be declared as static functions inside module source
|
||||
in order to keep smbd namespace unpolluted. See source of skel, audit, and recycle bin
|
||||
example VFS modules for more details.
|
||||
|
||||
*/
|
||||
|
||||
/* VFS operations structure */
|
||||
|
||||
@ -135,4 +179,157 @@ struct vfs_options {
|
||||
char *value;
|
||||
};
|
||||
|
||||
/*
|
||||
Available VFS operations. These values must be in sync with vfs_ops struct.
|
||||
In particular, if new operations are added to vfs_ops, appropriate constants
|
||||
should be added to vfs_op_type so that order of them kept same as in vfs_ops.
|
||||
*/
|
||||
|
||||
typedef enum _vfs_op_type {
|
||||
|
||||
SMB_VFS_OP_NOOP = -1,
|
||||
|
||||
/* Disk operations */
|
||||
|
||||
SMB_VFS_OP_CONNECT = 0,
|
||||
SMB_VFS_OP_DISCONNECT,
|
||||
SMB_VFS_OP_DISK_FREE,
|
||||
|
||||
/* Directory operations */
|
||||
|
||||
SMB_VFS_OP_OPENDIR,
|
||||
SMB_VFS_OP_READDIR,
|
||||
SMB_VFS_OP_MKDIR,
|
||||
SMB_VFS_OP_RMDIR,
|
||||
SMB_VFS_OP_CLOSEDIR,
|
||||
|
||||
/* File operations */
|
||||
|
||||
SMB_VFS_OP_OPEN,
|
||||
SMB_VFS_OP_CLOSE,
|
||||
SMB_VFS_OP_READ,
|
||||
SMB_VFS_OP_WRITE,
|
||||
SMB_VFS_OP_LSEEK,
|
||||
SMB_VFS_OP_RENAME,
|
||||
SMB_VFS_OP_FSYNC,
|
||||
SMB_VFS_OP_STAT,
|
||||
SMB_VFS_OP_FSTAT,
|
||||
SMB_VFS_OP_LSTAT,
|
||||
SMB_VFS_OP_UNLINK,
|
||||
SMB_VFS_OP_CHMOD,
|
||||
SMB_VFS_OP_FCHMOD,
|
||||
SMB_VFS_OP_CHOWN,
|
||||
SMB_VFS_OP_FCHOWN,
|
||||
SMB_VFS_OP_CHDIR,
|
||||
SMB_VFS_OP_GETWD,
|
||||
SMB_VFS_OP_UTIME,
|
||||
SMB_VFS_OP_FTRUNCATE,
|
||||
SMB_VFS_OP_LOCK,
|
||||
SMB_VFS_OP_SYMLINK,
|
||||
SMB_VFS_OP_READLINK,
|
||||
SMB_VFS_OP_LINK,
|
||||
SMB_VFS_OP_MKNOD,
|
||||
SMB_VFS_OP_REALPATH,
|
||||
|
||||
/* NT ACL operations. */
|
||||
|
||||
SMB_VFS_OP_FGET_NT_ACL,
|
||||
SMB_VFS_OP_GET_NT_ACL,
|
||||
SMB_VFS_OP_FSET_NT_ACL,
|
||||
SMB_VFS_OP_SET_NT_ACL,
|
||||
|
||||
/* POSIX ACL operations. */
|
||||
|
||||
SMB_VFS_OP_CHMOD_ACL,
|
||||
SMB_VFS_OP_FCHMOD_ACL,
|
||||
|
||||
SMB_VFS_OP_SYS_ACL_GET_ENTRY,
|
||||
SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE,
|
||||
SMB_VFS_OP_SYS_ACL_GET_PERMSET,
|
||||
SMB_VFS_OP_SYS_ACL_GET_QUALIFIER,
|
||||
SMB_VFS_OP_SYS_ACL_GET_FILE,
|
||||
SMB_VFS_OP_SYS_ACL_GET_FD,
|
||||
SMB_VFS_OP_SYS_ACL_CLEAR_PERMS,
|
||||
SMB_VFS_OP_SYS_ACL_ADD_PERM,
|
||||
SMB_VFS_OP_SYS_ACL_TO_TEXT,
|
||||
SMB_VFS_OP_SYS_ACL_INIT,
|
||||
SMB_VFS_OP_SYS_ACL_CREATE_ENTRY,
|
||||
SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE,
|
||||
SMB_VFS_OP_SYS_ACL_SET_QUALIFIER,
|
||||
SMB_VFS_OP_SYS_ACL_SET_PERMSET,
|
||||
SMB_VFS_OP_SYS_ACL_VALID,
|
||||
SMB_VFS_OP_SYS_ACL_SET_FILE,
|
||||
SMB_VFS_OP_SYS_ACL_SET_FD,
|
||||
SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
|
||||
SMB_VFS_OP_SYS_ACL_GET_PERM,
|
||||
SMB_VFS_OP_SYS_ACL_FREE_TEXT,
|
||||
SMB_VFS_OP_SYS_ACL_FREE_ACL,
|
||||
SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER,
|
||||
|
||||
/* This should always be last enum value */
|
||||
|
||||
SMB_VFS_OP_LAST
|
||||
} vfs_op_type;
|
||||
|
||||
/*
|
||||
Possible VFS operation layers (per-operation)
|
||||
|
||||
These values are used by VFS subsystem when building vfs_ops for connection
|
||||
from multiple VFS modules. Internally, Samba differentiates only opaque and
|
||||
transparent layers at this process. Other types are used for providing better
|
||||
diagnosing facilities.
|
||||
|
||||
Most modules will provide transparent layers. Opaque layer is for modules
|
||||
which implement actual file system calls (like DB-based VFS). For example,
|
||||
default POSIX VFS which is built in into Samba is an opaque VFS module.
|
||||
|
||||
Other layer types (audit, splitter, scanner) were designed to provide different
|
||||
degree of transparency and for diagnosing VFS module behaviour.
|
||||
|
||||
Each module can implement several layers at the same time provided that only
|
||||
one layer is used per each operation.
|
||||
|
||||
*/
|
||||
|
||||
typedef enum _vfs_op_layer {
|
||||
SMB_VFS_LAYER_NOOP = -1, /* - For using in VFS module to indicate end of array */
|
||||
/* of operations description */
|
||||
SMB_VFS_LAYER_OPAQUE = 0, /* - Final level, does not call anything beyond itself */
|
||||
SMB_VFS_LAYER_TRANSPARENT, /* - Normal operation, calls underlying layer after */
|
||||
/* possibly changing passed data */
|
||||
SMB_VFS_LAYER_LOGGER, /* - Logs data, calls underlying layer, logging does not */
|
||||
/* use Samba VFS */
|
||||
SMB_VFS_LAYER_SPLITTER, /* - Splits operation, calls underlying layer _and_ own facility, */
|
||||
/* then combines result */
|
||||
SMB_VFS_LAYER_SCANNER /* - Checks data and possibly initiates additional */
|
||||
/* file activity like logging to files _inside_ samba VFS */
|
||||
} vfs_op_layer;
|
||||
|
||||
/*
|
||||
VFS operation description. Each VFS module initialization function returns to VFS subsystem
|
||||
an array of vfs_op_tuple which describes all operations this module is willing to intercept.
|
||||
VFS subsystem initializes then vfs_ops using this information and passes it
|
||||
to next VFS module as underlying vfs_ops and to connection after all VFS modules are initialized.
|
||||
*/
|
||||
|
||||
typedef struct _vfs_op_tuple {
|
||||
void* op;
|
||||
vfs_op_type type;
|
||||
vfs_op_layer layer;
|
||||
} vfs_op_tuple;
|
||||
|
||||
/*
|
||||
Return vfs_ops filled with current opaque VFS operations. This function is designed to
|
||||
be called from VFS module initialization function for those modules which needs 'direct' VFS
|
||||
access (loggers or initiators of file operations other than connection asks for).
|
||||
|
||||
Returned vfs_ops must be cleaned up in VFS module's finalizer function (vfs_done_<module_name>)
|
||||
using safe_free().
|
||||
|
||||
Prototype:
|
||||
struct vfs_ops *smb_vfs_get_opaque_ops();
|
||||
|
||||
This prototype will be available via include/proto.h
|
||||
*/
|
||||
|
||||
#endif /* _VFS_H */
|
||||
|
@ -106,8 +106,10 @@ BOOL lang_tdb_init(const char *lang)
|
||||
|
||||
if (initialised) {
|
||||
/* we are re-initialising, free up any old init */
|
||||
tdb_close(tdb);
|
||||
tdb = NULL;
|
||||
if (tdb) {
|
||||
tdb_close(tdb);
|
||||
tdb = NULL;
|
||||
}
|
||||
SAFE_FREE(current_lang);
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
* Unix SMB/CIFS implementation.
|
||||
* account policy storage
|
||||
* Copyright (C) Jean François Micouleau 1998-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
|
||||
@ -31,6 +32,7 @@ BOOL init_account_policy(void)
|
||||
{
|
||||
static pid_t local_pid;
|
||||
char *vstring = "INFO/version";
|
||||
uint32 version;
|
||||
|
||||
if (tdb && local_pid == sys_getpid())
|
||||
return True;
|
||||
@ -44,9 +46,9 @@ BOOL init_account_policy(void)
|
||||
|
||||
/* handle a Samba upgrade */
|
||||
tdb_lock_bystring(tdb, vstring);
|
||||
if (tdb_fetch_int32(tdb, vstring) != DATABASE_VERSION) {
|
||||
if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
|
||||
tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
|
||||
tdb_store_int32(tdb, vstring, DATABASE_VERSION);
|
||||
tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
|
||||
|
||||
account_policy_set(AP_MIN_PASSWORD_LEN, MINPASSWDLENGTH); /* 5 chars minimum */
|
||||
account_policy_set(AP_PASSWORD_HISTORY, 0); /* don't keep any old password */
|
||||
@ -63,33 +65,50 @@ BOOL init_account_policy(void)
|
||||
return True;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
int field;
|
||||
char *string;
|
||||
} account_policy_names[] = {
|
||||
{AP_MIN_PASSWORD_LEN, "min password length"},
|
||||
{AP_PASSWORD_HISTORY, "password history"},
|
||||
{AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password"},
|
||||
{AP_MAX_PASSWORD_AGE, "maximum password age"},
|
||||
{AP_MIN_PASSWORD_AGE,"minimum password age"},
|
||||
{AP_LOCK_ACCOUNT_DURATION, "lockout duration"},
|
||||
{AP_RESET_COUNT_TIME, "reset count minutes"},
|
||||
{AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt"},
|
||||
{AP_TIME_TO_LOGOUT, "disconnect time"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
Get the account policy name as a string from its #define'ed number
|
||||
****************************************************************************/
|
||||
|
||||
static char *decode_account_policy_name(int field)
|
||||
static const char *decode_account_policy_name(int field)
|
||||
{
|
||||
switch (field) {
|
||||
case AP_MIN_PASSWORD_LEN:
|
||||
return "min password length";
|
||||
case AP_PASSWORD_HISTORY:
|
||||
return "password history";
|
||||
case AP_USER_MUST_LOGON_TO_CHG_PASS:
|
||||
return "user must logon to change password";
|
||||
case AP_MAX_PASSWORD_AGE:
|
||||
return "maximum password age";
|
||||
case AP_MIN_PASSWORD_AGE:
|
||||
return "minimum password age";
|
||||
case AP_LOCK_ACCOUNT_DURATION:
|
||||
return "lockout duration";
|
||||
case AP_RESET_COUNT_TIME:
|
||||
return "reset count minutes";
|
||||
case AP_BAD_ATTEMPT_LOCKOUT:
|
||||
return "bad lockout attempt";
|
||||
case AP_TIME_TO_LOGOUT:
|
||||
return "disconnect time";
|
||||
default:
|
||||
return "undefined value";
|
||||
int i;
|
||||
for (i=0; account_policy_names[i].string; i++) {
|
||||
if (field == account_policy_names[i].field)
|
||||
return account_policy_names[i].string;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Get the account policy name as a string from its #define'ed number
|
||||
****************************************************************************/
|
||||
|
||||
int account_policy_name_to_fieldnum(const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i=0; account_policy_names[i].string; i++) {
|
||||
if (strcmp(name, account_policy_names[i].string) == 0)
|
||||
return account_policy_names[i].field;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -101,8 +120,17 @@ BOOL account_policy_get(int field, uint32 *value)
|
||||
|
||||
init_account_policy();
|
||||
|
||||
*value = 0;
|
||||
|
||||
fstrcpy(name, decode_account_policy_name(field));
|
||||
*value=tdb_fetch_int32(tdb, name);
|
||||
if (!*name) {
|
||||
DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field));
|
||||
return False;
|
||||
}
|
||||
if (!tdb_fetch_uint32(tdb, name, value)) {
|
||||
DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for feild %d (%s), returning 0", field, name));
|
||||
return False;
|
||||
}
|
||||
DEBUG(10,("account_policy_get: %s:%d\n", name, *value));
|
||||
return True;
|
||||
}
|
||||
@ -117,8 +145,16 @@ BOOL account_policy_set(int field, uint32 value)
|
||||
init_account_policy();
|
||||
|
||||
fstrcpy(name, decode_account_policy_name(field));
|
||||
if ( tdb_store_int32(tdb, name, value)== -1)
|
||||
if (!*name) {
|
||||
DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", field));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!tdb_store_uint32(tdb, name, value)) {
|
||||
DEBUG(1, ("tdb_store_uint32 failed for feild %d (%s) on value %u", field, name, value));
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(10,("account_policy_set: %s:%d\n", name, value));
|
||||
|
||||
return True;
|
||||
|
@ -249,15 +249,15 @@ convert:
|
||||
size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
|
||||
void const *src, size_t srclen, void **dest)
|
||||
{
|
||||
void *ob;
|
||||
void *alloced_string;
|
||||
size_t dest_len;
|
||||
|
||||
*dest = NULL;
|
||||
dest_len=convert_string_allocate(from, to, src, srclen, (void **)&ob);
|
||||
dest_len=convert_string_allocate(from, to, src, srclen, &alloced_string);
|
||||
if (dest_len == -1)
|
||||
return -1;
|
||||
*dest = talloc_strdup(ctx, (char *)ob);
|
||||
SAFE_FREE(ob);
|
||||
*dest = talloc_memdup(ctx, alloced_string, dest_len);
|
||||
SAFE_FREE(alloced_string);
|
||||
if (*dest == NULL)
|
||||
return -1;
|
||||
return dest_len;
|
||||
@ -505,12 +505,12 @@ int push_utf8_pstring(void *dest, const char *src)
|
||||
*
|
||||
* @retval The number of bytes occupied by the string in the destination
|
||||
**/
|
||||
int push_utf8_talloc(TALLOC_CTX *ctx, void **dest, const char *src)
|
||||
int push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
|
||||
{
|
||||
int src_len = strlen(src)+1;
|
||||
|
||||
*dest = NULL;
|
||||
return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, dest);
|
||||
return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void**)dest);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -562,7 +562,8 @@ int pull_ucs2(const void *base_ptr, char *dest, const void *src, int dest_len, i
|
||||
}
|
||||
|
||||
/* ucs2 is always a multiple of 2 bytes */
|
||||
src_len &= ~1;
|
||||
if (src_len != -1)
|
||||
src_len &= ~1;
|
||||
|
||||
ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len);
|
||||
if (dest_len) dest[MIN(ret, dest_len-1)] = 0;
|
||||
@ -658,11 +659,11 @@ int pull_utf8_fstring(char *dest, const void *src)
|
||||
*
|
||||
* @retval The number of bytes occupied by the string in the destination
|
||||
**/
|
||||
int pull_utf8_talloc(TALLOC_CTX *ctx, void **dest, const char *src)
|
||||
int pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
|
||||
{
|
||||
int src_len = strlen(src)+1;
|
||||
*dest = NULL;
|
||||
return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, dest);
|
||||
return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,7 +423,7 @@ BOOL debug_parse_levels(const char *params_str)
|
||||
if (AllowDebugChange == False)
|
||||
return True;
|
||||
|
||||
params = str_list_make(params_str);
|
||||
params = str_list_make(params_str, NULL);
|
||||
|
||||
if (debug_parse_params(params, DEBUGLEVEL_CLASS,
|
||||
DEBUGLEVEL_CLASS_ISSET))
|
||||
@ -602,6 +602,12 @@ BOOL reopen_logs( void )
|
||||
force_check_log_size();
|
||||
(void)umask(oldumask);
|
||||
|
||||
/* Take over stderr to catch ouput into logs */
|
||||
if (dbf && sys_dup2(dbf->fd, 2) == -1) {
|
||||
close_low_fds(True); /* Close stderr too, if dup2 can't point it
|
||||
at the logfile */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ char *generate_random_str(size_t len)
|
||||
len = sizeof(retstr) -1;
|
||||
generate_random_buffer( retstr, len, False);
|
||||
for (i = 0; i < len; i++)
|
||||
retstr[i] = c_list[ retstr[i] % sizeof(c_list) ];
|
||||
retstr[i] = c_list[ retstr[i] % (sizeof(c_list)-1) ];
|
||||
|
||||
retstr[i] = '\0';
|
||||
|
||||
|
@ -428,3 +428,5 @@ char *rep_inet_ntoa(struct in_addr ip)
|
||||
}
|
||||
#endif /* HAVE_SYSLOG */
|
||||
#endif /* HAVE_VSYSLOG */
|
||||
|
||||
|
||||
|
@ -143,7 +143,7 @@ int smbrun(char *cmd, int *outfd)
|
||||
/* point our stdout at the file we want output to go into */
|
||||
if (outfd) {
|
||||
close(1);
|
||||
if (dup2(*outfd,1) != 1) {
|
||||
if (sys_dup2(*outfd,1) != 1) {
|
||||
DEBUG(2,("Failed to create stdout file descriptor\n"));
|
||||
close(*outfd);
|
||||
exit(80);
|
||||
|
@ -25,9 +25,41 @@ fstring local_machine="";
|
||||
fstring remote_arch="UNKNOWN";
|
||||
userdom_struct current_user_info;
|
||||
fstring remote_proto="UNKNOWN";
|
||||
fstring remote_machine="";
|
||||
extern pstring global_myname;
|
||||
|
||||
static fstring remote_machine="";
|
||||
|
||||
|
||||
void set_local_machine_name(const char* local_name)
|
||||
{
|
||||
fstring tmp_local_machine;
|
||||
|
||||
fstrcpy(tmp_local_machine,local_name);
|
||||
trim_string(tmp_local_machine," "," ");
|
||||
strlower(tmp_local_machine);
|
||||
alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
|
||||
}
|
||||
|
||||
void set_remote_machine_name(const char* remote_name)
|
||||
{
|
||||
fstring tmp_remote_machine;
|
||||
|
||||
fstrcpy(tmp_remote_machine,remote_name);
|
||||
trim_string(tmp_remote_machine," "," ");
|
||||
strlower(tmp_remote_machine);
|
||||
alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
|
||||
}
|
||||
|
||||
const char* get_remote_machine_name(void)
|
||||
{
|
||||
return remote_machine;
|
||||
}
|
||||
|
||||
const char* get_local_machine_name(void)
|
||||
{
|
||||
return local_machine;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Given a pointer to a %$(NAME) expand it as an environment variable.
|
||||
Return the number of characters by which the pointer should be advanced.
|
||||
@ -188,14 +220,15 @@ static char *automount_path(const char *user_name)
|
||||
moved out to a separate function.
|
||||
*******************************************************************/
|
||||
|
||||
static char *automount_server(const char *user_name)
|
||||
static const char *automount_server(const char *user_name)
|
||||
{
|
||||
static pstring server_name;
|
||||
const char *local_machine_name = get_local_machine_name();
|
||||
|
||||
/* use the local machine name as the default */
|
||||
/* this will be the default if WITH_AUTOMOUNT is not used or fails */
|
||||
if (*local_machine)
|
||||
pstrcpy(server_name, local_machine);
|
||||
if (local_machine_name && *local_machine_name)
|
||||
pstrcpy(server_name, local_machine_name);
|
||||
else
|
||||
pstrcpy(server_name, global_myname);
|
||||
|
||||
@ -229,6 +262,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
|
||||
char *p, *s;
|
||||
fstring pidstr;
|
||||
struct passwd *pass;
|
||||
const char *local_machine_name = get_local_machine_name();
|
||||
|
||||
for (s=str; (p=strchr_m(s, '%'));s=p) {
|
||||
fstring tmp_str;
|
||||
@ -261,8 +295,8 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
|
||||
string_sub(p,"%I", client_addr(),l);
|
||||
break;
|
||||
case 'L' :
|
||||
if (*local_machine)
|
||||
string_sub(p,"%L", local_machine,l);
|
||||
if (local_machine_name && *local_machine_name)
|
||||
string_sub(p,"%L", local_machine_name,l);
|
||||
else
|
||||
string_sub(p,"%L", global_myname,l);
|
||||
break;
|
||||
@ -286,7 +320,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
|
||||
string_sub(p,"%h", myhostname(),l);
|
||||
break;
|
||||
case 'm' :
|
||||
string_sub(p,"%m", remote_machine,l);
|
||||
string_sub(p,"%m", get_remote_machine_name(),l);
|
||||
break;
|
||||
case 'v' :
|
||||
string_sub(p,"%v", VERSION,l);
|
||||
@ -381,6 +415,7 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
|
||||
char *b, *p, *s, *t, *r, *a_string;
|
||||
fstring pidstr;
|
||||
struct passwd *pass;
|
||||
const char *local_machine_name = get_local_machine_name();
|
||||
|
||||
a_string = strdup(str);
|
||||
if (a_string == NULL) {
|
||||
@ -415,8 +450,8 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
|
||||
t = realloc_string_sub(t, "%I", client_addr());
|
||||
break;
|
||||
case 'L' :
|
||||
if (*local_machine)
|
||||
t = realloc_string_sub(t, "%L", local_machine);
|
||||
if (local_machine_name && *local_machine_name)
|
||||
t = realloc_string_sub(t, "%L", local_machine_name);
|
||||
else
|
||||
t = realloc_string_sub(t, "%L", global_myname);
|
||||
break;
|
||||
|
@ -1219,6 +1219,16 @@ const char *sys_dlerror(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
int sys_dup2(int oldfd, int newfd)
|
||||
{
|
||||
#if defined(HAVE_DUP2)
|
||||
return dup2(oldfd, newfd);
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Wrapper for Admin Logs.
|
||||
****************************************************************************/
|
||||
|
@ -163,7 +163,7 @@ BOOL map_username(char *user)
|
||||
}
|
||||
}
|
||||
|
||||
dosuserlist = str_list_make(dosname);
|
||||
dosuserlist = str_list_make(dosname, NULL);
|
||||
if (!dosuserlist) {
|
||||
DEBUG(0,("Unable to build user list\n"));
|
||||
return False;
|
||||
|
@ -100,7 +100,7 @@ char *tmpdir(void)
|
||||
Determine whether we are in the specified group.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
|
||||
BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -503,27 +503,32 @@ void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,ti
|
||||
/*******************************************************************
|
||||
close the low 3 fd's and open dev/null in their place
|
||||
********************************************************************/
|
||||
void close_low_fds(void)
|
||||
void close_low_fds(BOOL stderr_too)
|
||||
{
|
||||
int fd;
|
||||
int i;
|
||||
close(0); close(1);
|
||||
#ifndef __INSURE__
|
||||
close(2);
|
||||
#endif
|
||||
|
||||
if (stderr_too) {
|
||||
close(2);
|
||||
}
|
||||
|
||||
/* try and use up these file descriptors, so silly
|
||||
library routines writing to stdout etc won't cause havoc */
|
||||
for (i=0;i<3;i++) {
|
||||
fd = sys_open("/dev/null",O_RDWR,0);
|
||||
if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0);
|
||||
if (fd < 0) {
|
||||
DEBUG(0,("Can't open /dev/null\n"));
|
||||
return;
|
||||
}
|
||||
if (fd != i) {
|
||||
DEBUG(0,("Didn't get file descriptor %d\n",i));
|
||||
return;
|
||||
}
|
||||
if (i == 2 && !stderr_too)
|
||||
continue;
|
||||
|
||||
fd = sys_open("/dev/null",O_RDWR,0);
|
||||
if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0);
|
||||
if (fd < 0) {
|
||||
DEBUG(0,("Can't open /dev/null\n"));
|
||||
return;
|
||||
}
|
||||
if (fd != i) {
|
||||
DEBUG(0,("Didn't get file descriptor %d\n",i));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -678,7 +683,8 @@ void become_daemon(void)
|
||||
#endif /* HAVE_SETSID */
|
||||
|
||||
/* Close fd's 0,1,2. Needed if started by rsh */
|
||||
close_low_fds();
|
||||
close_low_fds(False); /* Don't close stderr, let the debug system
|
||||
attach it to the logfile */
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,27 +21,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#if 0
|
||||
static void print_grent_list(struct sys_grent *glist)
|
||||
{
|
||||
DEBUG(100, ("print_grent_list: %x\n", glist ));
|
||||
while (glist) {
|
||||
DEBUG(100,("glist: %x ", glist));
|
||||
if (glist->gr_name)
|
||||
DEBUG(100,(": gr_name = (%x) %s ", glist->gr_name, glist->gr_name));
|
||||
if (glist->gr_passwd)
|
||||
DEBUG(100,(": gr_passwd = (%x) %s ", glist->gr_passwd, glist->gr_passwd));
|
||||
if (glist->gr_mem) {
|
||||
int i;
|
||||
for (i = 0; glist->gr_mem[i]; i++)
|
||||
DEBUG(100,(" : gr_mem[%d] = (%x) %s ", i, glist->gr_mem[i], glist->gr_mem[i]));
|
||||
}
|
||||
DEBUG(100,(": gr_next = %x\n", glist->next ));
|
||||
glist = glist->next;
|
||||
}
|
||||
DEBUG(100,("FINISHED !\n\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************
|
||||
Returns a single linked list of group entries.
|
||||
|
@ -365,6 +365,9 @@ BOOL sid_parse(char *inbuf, size_t len, DOM_SID *sid)
|
||||
{
|
||||
int i;
|
||||
if (len < 8) return False;
|
||||
|
||||
ZERO_STRUCTP(sid);
|
||||
|
||||
sid->sid_rev_num = CVAL(inbuf, 0);
|
||||
sid->num_auths = CVAL(inbuf, 1);
|
||||
memcpy(sid->id_auth, inbuf+2, 6);
|
||||
|
@ -708,7 +708,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb
|
||||
|
||||
/* now we've got a socket - we need to bind it */
|
||||
if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
|
||||
if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) {
|
||||
if( DEBUGLVL(dlevel) && (port == SMB_PORT1 || port == SMB_PORT2 || port == NMB_PORT) ) {
|
||||
dbgtext( "bind failed on port %d ", port );
|
||||
dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) );
|
||||
dbgtext( "Error = %s\n", strerror(errno) );
|
||||
|
@ -212,6 +212,18 @@ int strwicmp(const char *psz1, const char *psz2)
|
||||
}
|
||||
|
||||
|
||||
/* Convert a string to upper case, but don't modify it */
|
||||
|
||||
char *strupper_static(const char *s)
|
||||
{
|
||||
static pstring str;
|
||||
|
||||
pstrcpy(str, s);
|
||||
strupper(str);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
convert a string to "normal" form
|
||||
********************************************************************/
|
||||
@ -299,7 +311,7 @@ BOOL trim_string(char *s,const char *front,const char *back)
|
||||
}
|
||||
|
||||
if (back_len) {
|
||||
while (strncmp(s+len-back_len,back,back_len)==0) {
|
||||
while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
|
||||
s[len-back_len]='\0';
|
||||
len -= back_len;
|
||||
ret=True;
|
||||
@ -667,7 +679,7 @@ void string_sub(char *s,const char *pattern, const char *insert, size_t len)
|
||||
li = (ssize_t)strlen(insert);
|
||||
|
||||
if (len == 0)
|
||||
len = ls;
|
||||
len = ls + 1; /* len is number of *bytes* */
|
||||
|
||||
while (lp <= ls && (p = strstr(s,pattern))) {
|
||||
if (ls + (li-lp) >= len) {
|
||||
@ -798,7 +810,7 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
|
||||
return;
|
||||
|
||||
if (len == 0)
|
||||
len = ls;
|
||||
len = ls + 1; /* len is number of *bytes* */
|
||||
|
||||
while (lp <= ls && (p = strstr(s,pattern))) {
|
||||
if (ls + (li-lp) >= len) {
|
||||
@ -826,7 +838,8 @@ return a new allocate unicode string.
|
||||
smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
|
||||
const smb_ucs2_t *insert)
|
||||
{
|
||||
smb_ucs2_t *r, *rp, *sp;
|
||||
smb_ucs2_t *r, *rp;
|
||||
const smb_ucs2_t *sp;
|
||||
size_t lr, lp, li, lt;
|
||||
|
||||
if (!insert || !pattern || !*pattern || !s) return NULL;
|
||||
@ -836,7 +849,7 @@ smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
|
||||
li = (size_t)strlen_w(insert);
|
||||
|
||||
if (li > lp) {
|
||||
smb_ucs2_t *st = s;
|
||||
const smb_ucs2_t *st = s;
|
||||
int ld = li - lp;
|
||||
while ((sp = strstr_w(st, pattern))) {
|
||||
st = sp + lp;
|
||||
@ -879,68 +892,59 @@ smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
splits out the front and back at a separator.
|
||||
Splits out the front and back at a separator.
|
||||
****************************************************************************/
|
||||
|
||||
void split_at_last_component(char *path, char *front, char sep, char *back)
|
||||
{
|
||||
char *p = strrchr_m(path, sep);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
if (front != NULL)
|
||||
{
|
||||
pstrcpy(front, path);
|
||||
}
|
||||
if (p != NULL)
|
||||
{
|
||||
|
||||
if (p != NULL) {
|
||||
if (back != NULL)
|
||||
{
|
||||
pstrcpy(back, p+1);
|
||||
}
|
||||
*p = '\\';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (back != NULL)
|
||||
{
|
||||
back[0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
write an octal as a string
|
||||
Write an octal as a string.
|
||||
****************************************************************************/
|
||||
|
||||
char *octal_string(int i)
|
||||
{
|
||||
static char ret[64];
|
||||
if (i == -1) {
|
||||
if (i == -1)
|
||||
return "-1";
|
||||
}
|
||||
slprintf(ret, sizeof(ret)-1, "0%o", i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
truncate a string at a specified length
|
||||
Truncate a string at a specified length.
|
||||
****************************************************************************/
|
||||
|
||||
char *string_truncate(char *s, int length)
|
||||
{
|
||||
if (s && strlen(s) > length) {
|
||||
if (s && strlen(s) > length)
|
||||
s[length] = 0;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
strchr and strrchr_m are very hard to do on general multi-byte strings.
|
||||
we convert via ucs2 for now
|
||||
Strchr and strrchr_m are very hard to do on general multi-byte strings.
|
||||
We convert via ucs2 for now.
|
||||
****************************************************************************/
|
||||
|
||||
char *strchr_m(const char *s, char c)
|
||||
{
|
||||
wpstring ws;
|
||||
@ -949,7 +953,8 @@ char *strchr_m(const char *s, char c)
|
||||
|
||||
push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
|
||||
p = strchr_w(ws, UCS2_CHAR(c));
|
||||
if (!p) return NULL;
|
||||
if (!p)
|
||||
return NULL;
|
||||
*p = 0;
|
||||
pull_ucs2_pstring(s2, ws);
|
||||
return (char *)(s+strlen(s2));
|
||||
@ -963,26 +968,29 @@ char *strrchr_m(const char *s, char c)
|
||||
|
||||
push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
|
||||
p = strrchr_w(ws, UCS2_CHAR(c));
|
||||
if (!p) return NULL;
|
||||
if (!p)
|
||||
return NULL;
|
||||
*p = 0;
|
||||
pull_ucs2_pstring(s2, ws);
|
||||
return (char *)(s+strlen(s2));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
convert a string to lower case
|
||||
Convert a string to lower case.
|
||||
********************************************************************/
|
||||
|
||||
void strlower_m(char *s)
|
||||
{
|
||||
/* this is quite a common operation, so we want it to be
|
||||
fast. We optimise for the ascii case, knowing that all our
|
||||
supported multi-byte character sets are ascii-compatible
|
||||
(ie. they match for the first 128 chars) */
|
||||
while (*s && !(((unsigned char)s[0]) & 0x7F)) {
|
||||
*s++ = tolower((unsigned char)*s);
|
||||
}
|
||||
|
||||
if (!*s) return;
|
||||
while (*s && !(((unsigned char)s[0]) & 0x7F))
|
||||
*s++ = tolower((unsigned char)*s);
|
||||
|
||||
if (!*s)
|
||||
return;
|
||||
|
||||
/* I assume that lowercased string takes the same number of bytes
|
||||
* as source string even in UTF-8 encoding. (VIV) */
|
||||
@ -990,8 +998,9 @@ void strlower_m(char *s)
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
duplicate convert a string to lower case
|
||||
Duplicate convert a string to lower case.
|
||||
********************************************************************/
|
||||
|
||||
char *strdup_lower(const char *s)
|
||||
{
|
||||
char *t = strdup(s);
|
||||
@ -1004,19 +1013,21 @@ char *strdup_lower(const char *s)
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
convert a string to upper case
|
||||
Convert a string to upper case.
|
||||
********************************************************************/
|
||||
|
||||
void strupper_m(char *s)
|
||||
{
|
||||
/* this is quite a common operation, so we want it to be
|
||||
fast. We optimise for the ascii case, knowing that all our
|
||||
supported multi-byte character sets are ascii-compatible
|
||||
(ie. they match for the first 128 chars) */
|
||||
while (*s && !(((unsigned char)s[0]) & 0x7F)) {
|
||||
*s++ = toupper((unsigned char)*s);
|
||||
}
|
||||
|
||||
if (!*s) return;
|
||||
while (*s && !(((unsigned char)s[0]) & 0x7F))
|
||||
*s++ = toupper((unsigned char)*s);
|
||||
|
||||
if (!*s)
|
||||
return;
|
||||
|
||||
/* I assume that lowercased string takes the same number of bytes
|
||||
* as source string even in multibyte encoding. (VIV) */
|
||||
@ -1024,8 +1035,9 @@ void strupper_m(char *s)
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
convert a string to upper case
|
||||
Convert a string to upper case.
|
||||
********************************************************************/
|
||||
|
||||
char *strdup_upper(const char *s)
|
||||
{
|
||||
char *t = strdup(s);
|
||||
@ -1048,7 +1060,8 @@ char *binary_string(char *buf, int len)
|
||||
int i, j;
|
||||
const char *hex = "0123456789ABCDEF";
|
||||
s = malloc(len * 3 + 1);
|
||||
if (!s) return NULL;
|
||||
if (!s)
|
||||
return NULL;
|
||||
for (j=i=0;i<len;i++) {
|
||||
s[j] = '\\';
|
||||
s[j+1] = hex[((unsigned char)buf[i]) >> 4];
|
||||
@ -1059,8 +1072,8 @@ char *binary_string(char *buf, int len)
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* Just a typesafety wrapper for snprintf into a pstring */
|
||||
|
||||
int pstr_sprintf(pstring s, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@ -1072,8 +1085,8 @@ int pstr_sprintf(pstring s, const char *fmt, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Just a typesafety wrapper for snprintf into a fstring */
|
||||
|
||||
int fstr_sprintf(fstring s, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@ -1085,18 +1098,19 @@ int fstr_sprintf(fstring s, const char *fmt, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_STRNDUP
|
||||
/*******************************************************************
|
||||
some platforms don't have strndup
|
||||
Some platforms don't have strndup.
|
||||
********************************************************************/
|
||||
|
||||
char *strndup(const char *s, size_t n)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
n = strnlen(s, n);
|
||||
ret = malloc(n+1);
|
||||
if (!ret) return NULL;
|
||||
if (!ret)
|
||||
return NULL;
|
||||
memcpy(ret, s, n);
|
||||
ret[n] = 0;
|
||||
|
||||
@ -1111,39 +1125,39 @@ some platforms don't have strnlen
|
||||
size_t strnlen(const char *s, size_t n)
|
||||
{
|
||||
int i;
|
||||
for (i=0; s[i] && i<n; i++) /* noop */ ;
|
||||
for (i=0; s[i] && i<n; i++)
|
||||
/* noop */ ;
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/***********************************************************
|
||||
List of Strings manipulation functions
|
||||
***********************************************************/
|
||||
|
||||
#define S_LIST_ABS 16 /* List Allocation Block Size */
|
||||
|
||||
char **str_list_make(const char *string)
|
||||
char **str_list_make(const char *string, const char *sep)
|
||||
{
|
||||
char **list, **rlist;
|
||||
char *str, *s;
|
||||
int num, lsize;
|
||||
pstring tok;
|
||||
|
||||
if (!string || !*string) return NULL;
|
||||
if (!string || !*string)
|
||||
return NULL;
|
||||
s = strdup(string);
|
||||
if (!s) {
|
||||
DEBUG(0,("str_list_make: Unable to allocate memory"));
|
||||
return NULL;
|
||||
}
|
||||
if (!sep) sep = LIST_SEP;
|
||||
|
||||
num = lsize = 0;
|
||||
list = NULL;
|
||||
|
||||
str = s;
|
||||
while (next_token(&str, tok, LIST_SEP, sizeof(tok)))
|
||||
{
|
||||
while (next_token(&str, tok, sep, sizeof(tok))) {
|
||||
if (num == lsize) {
|
||||
lsize += S_LIST_ABS;
|
||||
rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
|
||||
@ -1178,13 +1192,13 @@ BOOL str_list_copy(char ***dest, char **src)
|
||||
int num, lsize;
|
||||
|
||||
*dest = NULL;
|
||||
if (!src) return False;
|
||||
if (!src)
|
||||
return False;
|
||||
|
||||
num = lsize = 0;
|
||||
list = NULL;
|
||||
|
||||
while (src[num])
|
||||
{
|
||||
while (src[num]) {
|
||||
if (num == lsize) {
|
||||
lsize += S_LIST_ABS;
|
||||
rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
|
||||
@ -1212,17 +1226,22 @@ BOOL str_list_copy(char ***dest, char **src)
|
||||
}
|
||||
|
||||
/* return true if all the elemnts of the list matches exactly */
|
||||
|
||||
BOOL str_list_compare(char **list1, char **list2)
|
||||
{
|
||||
int num;
|
||||
|
||||
if (!list1 || !list2) return (list1 == list2);
|
||||
if (!list1 || !list2)
|
||||
return (list1 == list2);
|
||||
|
||||
for (num = 0; list1[num]; num++) {
|
||||
if (!list2[num]) return False;
|
||||
if (!strcsequal(list1[num], list2[num])) return False;
|
||||
if (!list2[num])
|
||||
return False;
|
||||
if (!strcsequal(list1[num], list2[num]))
|
||||
return False;
|
||||
}
|
||||
if (list2[num]) return False; /* if list2 has more elements than list1 fail */
|
||||
if (list2[num])
|
||||
return False; /* if list2 has more elements than list1 fail */
|
||||
|
||||
return True;
|
||||
}
|
||||
@ -1231,9 +1250,11 @@ void str_list_free(char ***list)
|
||||
{
|
||||
char **tlist;
|
||||
|
||||
if (!list || !*list) return;
|
||||
if (!list || !*list)
|
||||
return;
|
||||
tlist = *list;
|
||||
for(; *tlist; tlist++) SAFE_FREE(*tlist);
|
||||
for(; *tlist; tlist++)
|
||||
SAFE_FREE(*tlist);
|
||||
SAFE_FREE(*list);
|
||||
}
|
||||
|
||||
@ -1242,25 +1263,25 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
|
||||
char *p, *s, *t;
|
||||
ssize_t ls, lp, li, ld, i, d;
|
||||
|
||||
if (!list) return False;
|
||||
if (!pattern) return False;
|
||||
if (!insert) return False;
|
||||
if (!list)
|
||||
return False;
|
||||
if (!pattern)
|
||||
return False;
|
||||
if (!insert)
|
||||
return False;
|
||||
|
||||
lp = (ssize_t)strlen(pattern);
|
||||
li = (ssize_t)strlen(insert);
|
||||
ld = li -lp;
|
||||
|
||||
while (*list)
|
||||
{
|
||||
while (*list) {
|
||||
s = *list;
|
||||
ls = (ssize_t)strlen(s);
|
||||
|
||||
while ((p = strstr(s, pattern)))
|
||||
{
|
||||
while ((p = strstr(s, pattern))) {
|
||||
t = *list;
|
||||
d = p -t;
|
||||
if (ld)
|
||||
{
|
||||
if (ld) {
|
||||
t = (char *) malloc(ls +ld +1);
|
||||
if (!t) {
|
||||
DEBUG(0,("str_list_substitute: Unable to allocate memory"));
|
||||
|
@ -236,7 +236,7 @@ char **wins_srv_tags(void)
|
||||
}
|
||||
|
||||
/* add it to the list */
|
||||
ret = (char **)Realloc(ret, (count+1) * sizeof(char *));
|
||||
ret = (char **)Realloc(ret, (count+2) * sizeof(char *));
|
||||
ret[count] = strdup(t_ip.tag);
|
||||
if (!ret[count]) break;
|
||||
count++;
|
||||
|
@ -171,7 +171,7 @@ int x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f)
|
||||
flush a bit more than necessary, but that is harmless */
|
||||
if (f->buftype == X_IOLBF && f->bufused) {
|
||||
int i;
|
||||
for (i=size-1; i>=0; i--) {
|
||||
for (i=(size*nmemb)-1; i>=0; i--) {
|
||||
if (*(i+(const char *)p) == '\n') {
|
||||
x_fflush(f);
|
||||
break;
|
||||
|
@ -72,47 +72,6 @@ char *ads_build_dn(const char *realm)
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_LDAP
|
||||
/*
|
||||
find the ldap server from DNS
|
||||
*/
|
||||
static char *find_ldap_server(ADS_STRUCT *ads)
|
||||
{
|
||||
char *list = NULL;
|
||||
struct in_addr ip;
|
||||
|
||||
if (ads->realm &&
|
||||
strcasecmp(ads->workgroup, lp_workgroup()) == 0 &&
|
||||
ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) {
|
||||
char *p;
|
||||
p = strchr(list, ':');
|
||||
if (p) *p = 0;
|
||||
return list;
|
||||
}
|
||||
|
||||
/* get desperate, find the domain controller IP */
|
||||
if (resolve_name(ads->workgroup, &ip, 0x1B)) {
|
||||
return strdup(inet_ntoa(ip));
|
||||
}
|
||||
|
||||
/* or a BDC ... */
|
||||
if (resolve_name(ads->workgroup, &ip, 0x1C)) {
|
||||
return strdup(inet_ntoa(ip));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static char *find_ldap_server(ADS_STRUCT *ads)
|
||||
{
|
||||
/* Without LDAP this doesn't make much sense */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef LDAP_PORT
|
||||
#define LDAP_PORT 389
|
||||
#endif
|
||||
@ -122,46 +81,24 @@ static char *find_ldap_server(ADS_STRUCT *ads)
|
||||
*/
|
||||
ADS_STRUCT *ads_init(const char *realm,
|
||||
const char *workgroup,
|
||||
const char *ldap_server,
|
||||
const char *bind_path,
|
||||
const char *password)
|
||||
const char *ldap_server)
|
||||
{
|
||||
ADS_STRUCT *ads;
|
||||
|
||||
ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads));
|
||||
ZERO_STRUCTP(ads);
|
||||
|
||||
if (!workgroup) {
|
||||
workgroup = lp_workgroup();
|
||||
}
|
||||
ads->server.realm = realm? strdup(realm) : NULL;
|
||||
ads->server.workgroup = workgroup ? strdup(workgroup) : NULL;
|
||||
ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL;
|
||||
|
||||
ads->realm = realm? strdup(realm) : NULL;
|
||||
ads->workgroup = strdup(workgroup);
|
||||
ads->ldap_server = ldap_server? strdup(ldap_server) : NULL;
|
||||
ads->bind_path = bind_path? strdup(bind_path) : NULL;
|
||||
ads->ldap_port = LDAP_PORT;
|
||||
if (password) ads->password = strdup(password);
|
||||
|
||||
if (!ads->realm) {
|
||||
ads->realm = strdup(lp_realm());
|
||||
if (!ads->realm[0]) {
|
||||
SAFE_FREE(ads->realm);
|
||||
}
|
||||
/* we need to know if this is a foreign realm to know if we can
|
||||
use lp_ads_server() */
|
||||
if (realm && strcasecmp(lp_realm(), realm) != 0) {
|
||||
ads->server.foreign = 1;
|
||||
}
|
||||
if (!ads->bind_path && ads->realm) {
|
||||
ads->bind_path = ads_build_dn(ads->realm);
|
||||
}
|
||||
if (!ads->ldap_server) {
|
||||
if (strcasecmp(ads->workgroup, lp_workgroup()) == 0) {
|
||||
ads->ldap_server = strdup(lp_ads_server());
|
||||
}
|
||||
if (!ads->ldap_server || !ads->ldap_server[0]) {
|
||||
ads->ldap_server = find_ldap_server(ads);
|
||||
}
|
||||
}
|
||||
if (!ads->kdc_server) {
|
||||
/* assume its the same as LDAP */
|
||||
ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL;
|
||||
if (workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) {
|
||||
ads->server.foreign = 1;
|
||||
}
|
||||
|
||||
return ads;
|
||||
@ -170,7 +107,7 @@ ADS_STRUCT *ads_init(const char *realm,
|
||||
/* a simpler ads_init() interface using all defaults */
|
||||
ADS_STRUCT *ads_init_simple(void)
|
||||
{
|
||||
return ads_init(NULL, NULL, NULL, NULL, NULL);
|
||||
return ads_init(NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -182,13 +119,19 @@ void ads_destroy(ADS_STRUCT **ads)
|
||||
#if HAVE_LDAP
|
||||
if ((*ads)->ld) ldap_unbind((*ads)->ld);
|
||||
#endif
|
||||
SAFE_FREE((*ads)->realm);
|
||||
SAFE_FREE((*ads)->ldap_server);
|
||||
SAFE_FREE((*ads)->ldap_server_name);
|
||||
SAFE_FREE((*ads)->kdc_server);
|
||||
SAFE_FREE((*ads)->bind_path);
|
||||
SAFE_FREE((*ads)->password);
|
||||
SAFE_FREE((*ads)->user_name);
|
||||
SAFE_FREE((*ads)->server.realm);
|
||||
SAFE_FREE((*ads)->server.workgroup);
|
||||
SAFE_FREE((*ads)->server.ldap_server);
|
||||
|
||||
SAFE_FREE((*ads)->auth.realm);
|
||||
SAFE_FREE((*ads)->auth.password);
|
||||
SAFE_FREE((*ads)->auth.user_name);
|
||||
SAFE_FREE((*ads)->auth.kdc_server);
|
||||
|
||||
SAFE_FREE((*ads)->config.realm);
|
||||
SAFE_FREE((*ads)->config.bind_path);
|
||||
SAFE_FREE((*ads)->config.ldap_server_name);
|
||||
|
||||
ZERO_STRUCTP(*ads);
|
||||
SAFE_FREE(*ads);
|
||||
}
|
||||
|
@ -110,16 +110,8 @@ int ads_kinit_password(ADS_STRUCT *ads)
|
||||
char *s;
|
||||
int ret;
|
||||
|
||||
if (!ads->user_name) {
|
||||
/* by default use the machine account */
|
||||
extern pstring global_myname;
|
||||
fstring myname;
|
||||
fstrcpy(myname, global_myname);
|
||||
strlower(myname);
|
||||
asprintf(&ads->user_name, "HOST/%s", global_myname);
|
||||
}
|
||||
asprintf(&s, "%s@%s", ads->user_name, ads->realm);
|
||||
ret = kerberos_kinit_password(s, ads->password);
|
||||
asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm);
|
||||
ret = kerberos_kinit_password(s, ads->auth.password);
|
||||
|
||||
if (ret) {
|
||||
DEBUG(0,("kerberos_kinit_password %s failed: %s\n",
|
||||
|
@ -67,7 +67,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
}
|
||||
|
||||
ret = krb5_set_default_realm(context, ads->realm);
|
||||
ret = krb5_set_default_realm(context, ads->auth.realm);
|
||||
if (ret) {
|
||||
DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret)));
|
||||
ads_destroy(&ads);
|
||||
|
@ -37,6 +37,165 @@
|
||||
* codepoints in UTF-8). This may have to change at some point
|
||||
**/
|
||||
|
||||
|
||||
/*
|
||||
try a connection to a given ldap server, returning True and setting the servers IP
|
||||
in the ads struct if successful
|
||||
*/
|
||||
static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port)
|
||||
{
|
||||
char *srv;
|
||||
|
||||
if (!server || !*server) {
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(5,("ads_try_connect: trying ldap server '%s' port %u\n", server, port));
|
||||
|
||||
/* this copes with inet_ntoa brokenness */
|
||||
srv = strdup(server);
|
||||
|
||||
ads->ld = ldap_open(srv, port);
|
||||
if (!ads->ld) {
|
||||
free(srv);
|
||||
return False;
|
||||
}
|
||||
ads->ldap_port = port;
|
||||
ads->ldap_ip = *interpret_addr2(srv);
|
||||
free(srv);
|
||||
return True;
|
||||
}
|
||||
|
||||
/* used by the IP comparison function */
|
||||
struct ldap_ip {
|
||||
struct in_addr ip;
|
||||
unsigned port;
|
||||
};
|
||||
|
||||
/* compare 2 ldap IPs by nearness to our interfaces - used in qsort */
|
||||
static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2)
|
||||
{
|
||||
return ip_compare(&ip1->ip, &ip2->ip);
|
||||
}
|
||||
|
||||
/* try connecting to a ldap server via DNS */
|
||||
static BOOL ads_try_dns(ADS_STRUCT *ads)
|
||||
{
|
||||
char *realm, *ptr;
|
||||
char *list = NULL;
|
||||
pstring tok;
|
||||
struct ldap_ip *ip_list;
|
||||
int count, i=0;
|
||||
|
||||
realm = ads->server.realm;
|
||||
if (!realm || !*realm) {
|
||||
realm = lp_realm();
|
||||
}
|
||||
if (!realm || !*realm) {
|
||||
realm = ads->server.workgroup;
|
||||
}
|
||||
if (!realm || !*realm) {
|
||||
realm = lp_workgroup();
|
||||
}
|
||||
if (!realm) {
|
||||
return False;
|
||||
}
|
||||
realm = smb_xstrdup(realm);
|
||||
|
||||
DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm));
|
||||
if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) {
|
||||
SAFE_FREE(realm);
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list));
|
||||
SAFE_FREE(realm);
|
||||
|
||||
count = count_chars(list, ' ') + 1;
|
||||
ip_list = malloc(count * sizeof(struct ldap_ip));
|
||||
if (!ip_list) {
|
||||
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);
|
||||
}
|
||||
ip_list[i].ip = *interpret_addr2(tok);
|
||||
ip_list[i].port = port;
|
||||
if (!is_zero_ip(ip_list[i].ip)) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
free(list);
|
||||
|
||||
count = i;
|
||||
|
||||
/* we sort the list of addresses by closeness to our interfaces. This
|
||||
tries to prevent us using a DC on the other side of the country */
|
||||
if (count > 1) {
|
||||
qsort(ip_list, count, sizeof(struct ldap_ip),
|
||||
QSORT_CAST ldap_ip_compare);
|
||||
}
|
||||
|
||||
for (i=0;i<count;i++) {
|
||||
if (ads_try_connect(ads, inet_ntoa(ip_list[i].ip), ip_list[i].port)) {
|
||||
free(ip_list);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE(ip_list);
|
||||
return False;
|
||||
}
|
||||
|
||||
/* try connecting to a ldap server via netbios */
|
||||
static BOOL ads_try_netbios(ADS_STRUCT *ads)
|
||||
{
|
||||
struct in_addr *ip_list;
|
||||
int count;
|
||||
int i;
|
||||
char *workgroup = ads->server.workgroup;
|
||||
|
||||
if (!workgroup) {
|
||||
workgroup = lp_workgroup();
|
||||
}
|
||||
|
||||
DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup));
|
||||
|
||||
/* try the PDC first */
|
||||
if (get_dc_list(True, workgroup, &ip_list, &count)) {
|
||||
for (i=0;i<count;i++) {
|
||||
DEBUG(6,("ads_try_netbios: trying server '%s'\n",
|
||||
inet_ntoa(ip_list[i])));
|
||||
if (ads_try_connect(ads, inet_ntoa(ip_list[i]), LDAP_PORT)) {
|
||||
free(ip_list);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
free(ip_list);
|
||||
}
|
||||
|
||||
/* now any DC, including backups */
|
||||
if (get_dc_list(False, workgroup, &ip_list, &count)) {
|
||||
for (i=0;i<count;i++) {
|
||||
DEBUG(6,("ads_try_netbios: trying server '%s'\n",
|
||||
inet_ntoa(ip_list[i])));
|
||||
if (ads_try_connect(ads, inet_ntoa(ip_list[i]), LDAP_PORT)) {
|
||||
free(ip_list);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
free(ip_list);
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the LDAP server
|
||||
* @param ads Pointer to an existing ADS_STRUCT
|
||||
@ -49,38 +208,35 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
|
||||
ADS_STATUS status;
|
||||
|
||||
ads->last_attempt = time(NULL);
|
||||
|
||||
ads->ld = NULL;
|
||||
|
||||
if (ads->ldap_server) {
|
||||
ads->ld = ldap_open(ads->ldap_server, ads->ldap_port);
|
||||
/* try with a user specified server */
|
||||
if (ads->server.ldap_server &&
|
||||
ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) {
|
||||
goto got_connection;
|
||||
}
|
||||
|
||||
/* if that failed then try each of the BDC's in turn */
|
||||
if (!ads->ld) {
|
||||
struct in_addr *ip_list;
|
||||
int count;
|
||||
/* try with a smb.conf ads server setting if we are connecting
|
||||
to the primary workgroup or realm */
|
||||
if (!ads->server.foreign &&
|
||||
ads_try_connect(ads, lp_ads_server(), LDAP_PORT)) {
|
||||
goto got_connection;
|
||||
}
|
||||
|
||||
if (get_dc_list(False, ads->workgroup, &ip_list, &count)) {
|
||||
int i;
|
||||
for (i=0;i<count;i++) {
|
||||
ads->ld = ldap_open(inet_ntoa(ip_list[i]),
|
||||
ads->ldap_port);
|
||||
if (ads->ld) break;
|
||||
}
|
||||
if (ads->ld) {
|
||||
SAFE_FREE(ads->ldap_server);
|
||||
ads->ldap_server = strdup(inet_ntoa(ip_list[i]));
|
||||
}
|
||||
free(ip_list);
|
||||
/* try via DNS */
|
||||
if (ads_try_dns(ads)) {
|
||||
goto got_connection;
|
||||
}
|
||||
|
||||
/* try via netbios lookups */
|
||||
if (!lp_disable_netbios() && ads_try_netbios(ads)) {
|
||||
goto got_connection;
|
||||
}
|
||||
|
||||
if (!ads->ld) {
|
||||
return ADS_ERROR_SYSTEM(errno);
|
||||
}
|
||||
return ADS_ERROR_SYSTEM(errno?errno:ENOENT);
|
||||
|
||||
DEBUG(3,("Connected to LDAP server %s\n", ads->ldap_server));
|
||||
got_connection:
|
||||
DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip)));
|
||||
|
||||
status = ads_server_info(ads);
|
||||
if (!ADS_ERR_OK(status)) {
|
||||
@ -90,22 +246,43 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
|
||||
|
||||
ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
|
||||
|
||||
if (!ads->auth.user_name) {
|
||||
/* by default use the machine account */
|
||||
extern pstring global_myname;
|
||||
fstring myname;
|
||||
fstrcpy(myname, global_myname);
|
||||
strlower(myname);
|
||||
asprintf(&ads->auth.user_name, "HOST/%s", myname);
|
||||
}
|
||||
|
||||
if (!ads->auth.realm) {
|
||||
ads->auth.realm = strdup(ads->config.realm);
|
||||
}
|
||||
|
||||
if (!ads->auth.kdc_server) {
|
||||
ads->auth.kdc_server = strdup(inet_ntoa(ads->ldap_ip));
|
||||
}
|
||||
|
||||
#if KRB5_DNS_HACK
|
||||
/* this is a really nasty hack to avoid ADS DNS problems. It needs a patch
|
||||
to MIT kerberos to work (tridge) */
|
||||
{
|
||||
char *env;
|
||||
asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->server_realm);
|
||||
setenv(env, inet_ntoa(*interpret_addr2(ads->ldap_server)), 1);
|
||||
asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->config.realm);
|
||||
setenv(env, ads->auth.kdc_server, 1);
|
||||
free(env);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ads->password) {
|
||||
if (ads->auth.password) {
|
||||
if ((code = ads_kinit_password(ads)))
|
||||
return ADS_ERROR_KRB5(code);
|
||||
}
|
||||
|
||||
if (ads->auth.no_bind) {
|
||||
return ADS_SUCCESS;
|
||||
}
|
||||
|
||||
return ads_sasl_bind(ads);
|
||||
}
|
||||
|
||||
@ -161,7 +338,7 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals)
|
||||
if (!values) return NULL;
|
||||
|
||||
for (i=0; in_vals[i]; i++) {
|
||||
push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]);
|
||||
push_utf8_talloc(ctx, &values[i], in_vals[i]);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
@ -180,7 +357,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals)
|
||||
if (!values) return NULL;
|
||||
|
||||
for (i=0; in_vals[i]; i++) {
|
||||
pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]);
|
||||
pull_utf8_talloc(ctx, &values[i], in_vals[i]);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
@ -219,8 +396,8 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
|
||||
/* 0 means the conversion worked but the result was empty
|
||||
so we only fail if it's negative. In any case, it always
|
||||
at least nulls out the dest */
|
||||
if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) ||
|
||||
(push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) {
|
||||
if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) ||
|
||||
(push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
@ -230,7 +407,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
|
||||
else {
|
||||
/* This would be the utf8-encoded version...*/
|
||||
/* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */
|
||||
if (!(str_list_copy(&search_attrs, (char **) attrs)))
|
||||
if (!(str_list_copy(&search_attrs, attrs)))
|
||||
{
|
||||
rc = LDAP_NO_MEMORY;
|
||||
goto done;
|
||||
@ -442,8 +619,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
|
||||
/* 0 means the conversion worked but the result was empty
|
||||
so we only fail if it's negative. In any case, it always
|
||||
at least nulls out the dest */
|
||||
if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) ||
|
||||
(push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) {
|
||||
if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) ||
|
||||
(push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
@ -453,7 +630,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
|
||||
else {
|
||||
/* This would be the utf8-encoded version...*/
|
||||
/* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */
|
||||
if (!(str_list_copy(&search_attrs, (char **) attrs)))
|
||||
if (!(str_list_copy(&search_attrs, attrs)))
|
||||
{
|
||||
rc = LDAP_NO_MEMORY;
|
||||
goto done;
|
||||
@ -494,7 +671,7 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res,
|
||||
const char *exp,
|
||||
const char **attrs)
|
||||
{
|
||||
return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE,
|
||||
return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
|
||||
exp, attrs, res);
|
||||
}
|
||||
|
||||
@ -805,11 +982,11 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
|
||||
|
||||
if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname)))
|
||||
goto done;
|
||||
if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->realm)))
|
||||
if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm)))
|
||||
goto done;
|
||||
ou_str = ads_ou_string(org_unit);
|
||||
new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str,
|
||||
ads->bind_path);
|
||||
ads->config.bind_path);
|
||||
free(ou_str);
|
||||
if (!new_dn)
|
||||
goto done;
|
||||
@ -925,6 +1102,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area)
|
||||
} handlers[] = {
|
||||
{"objectGUID", False, dump_binary},
|
||||
{"nTSecurityDescriptor", False, dump_sd},
|
||||
{"dnsRecord", False, dump_binary},
|
||||
{"objectSid", False, dump_sid},
|
||||
{NULL, True, NULL}
|
||||
};
|
||||
@ -999,7 +1177,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res,
|
||||
char *field;
|
||||
BOOL string;
|
||||
|
||||
pull_utf8_talloc(ctx, (void **) &field, utf8_field);
|
||||
pull_utf8_talloc(ctx, &field, utf8_field);
|
||||
string = fn(field, NULL, data_area);
|
||||
|
||||
if (string) {
|
||||
@ -1061,7 +1239,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org
|
||||
status = ads_leave_realm(ads, host);
|
||||
if (!ADS_ERR_OK(status)) {
|
||||
DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n",
|
||||
host, ads->realm));
|
||||
host, ads->config.realm));
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@ -1224,20 +1402,15 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
|
||||
char *host = strdup(hostname);
|
||||
char *principal;
|
||||
|
||||
if (!ads->kdc_server) {
|
||||
DEBUG(0, ("Unable to find KDC server\n"));
|
||||
return ADS_ERROR(LDAP_SERVER_DOWN);
|
||||
}
|
||||
|
||||
strlower(host);
|
||||
|
||||
/*
|
||||
we need to use the '$' form of the name here, as otherwise the
|
||||
server might end up setting the password for a user instead
|
||||
*/
|
||||
asprintf(&principal, "%s$@%s", host, ads->realm);
|
||||
asprintf(&principal, "%s$@%s", host, ads->auth.realm);
|
||||
|
||||
status = krb5_set_password(ads->kdc_server, principal, password);
|
||||
status = krb5_set_password(ads->auth.kdc_server, principal, password);
|
||||
|
||||
free(host);
|
||||
free(principal);
|
||||
@ -1287,7 +1460,7 @@ char *ads_pull_string(ADS_STRUCT *ads,
|
||||
if (!values) return NULL;
|
||||
|
||||
if (values[0]) {
|
||||
rc = pull_utf8_talloc(mem_ctx, (void **)&ux_string,
|
||||
rc = pull_utf8_talloc(mem_ctx, &ux_string,
|
||||
values[0]);
|
||||
if (rc != -1)
|
||||
ret = ux_string;
|
||||
@ -1321,7 +1494,7 @@ char **ads_pull_strings(ADS_STRUCT *ads,
|
||||
ret = talloc(mem_ctx, sizeof(char *) * (n+1));
|
||||
|
||||
for (i=0;i<n;i++) {
|
||||
if (pull_utf8_talloc(mem_ctx, (void **)&ret[i], values[i]) == -1) {
|
||||
if (pull_utf8_talloc(mem_ctx, &ret[i], values[i]) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1472,33 +1645,27 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
|
||||
return ADS_ERROR(LDAP_DECODING_ERROR);
|
||||
}
|
||||
|
||||
SAFE_FREE(ads->ldap_server_name);
|
||||
SAFE_FREE(ads->config.ldap_server_name);
|
||||
|
||||
ads->ldap_server_name = strdup(p+1);
|
||||
p = strchr(ads->ldap_server_name, '$');
|
||||
ads->config.ldap_server_name = strdup(p+1);
|
||||
p = strchr(ads->config.ldap_server_name, '$');
|
||||
if (!p || p[1] != '@') {
|
||||
ldap_value_free(values);
|
||||
ldap_msgfree(res);
|
||||
SAFE_FREE(ads->ldap_server_name);
|
||||
SAFE_FREE(ads->config.ldap_server_name);
|
||||
return ADS_ERROR(LDAP_DECODING_ERROR);
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
|
||||
SAFE_FREE(ads->server_realm);
|
||||
SAFE_FREE(ads->bind_path);
|
||||
SAFE_FREE(ads->config.realm);
|
||||
SAFE_FREE(ads->config.bind_path);
|
||||
|
||||
ads->server_realm = strdup(p+2);
|
||||
ads->bind_path = ads_build_dn(ads->server_realm);
|
||||
|
||||
/* in case the realm isn't configured in smb.conf */
|
||||
if (!ads->realm || !ads->realm[0]) {
|
||||
SAFE_FREE(ads->realm);
|
||||
ads->realm = strdup(ads->server_realm);
|
||||
}
|
||||
ads->config.realm = strdup(p+2);
|
||||
ads->config.bind_path = ads_build_dn(ads->config.realm);
|
||||
|
||||
DEBUG(3,("got ldap server name %s@%s\n",
|
||||
ads->ldap_server_name, ads->realm));
|
||||
ads->config.ldap_server_name, ads->config.realm));
|
||||
|
||||
return ADS_SUCCESS;
|
||||
}
|
||||
@ -1514,9 +1681,13 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
|
||||
* @return the count of SIDs pulled
|
||||
**/
|
||||
ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
|
||||
int *num_trusts, char ***names, DOM_SID **sids)
|
||||
int *num_trusts,
|
||||
char ***names,
|
||||
char ***alt_names,
|
||||
DOM_SID **sids)
|
||||
{
|
||||
const char *attrs[] = {"flatName", "securityIdentifier", NULL};
|
||||
const char *attrs[] = {"name", "flatname", "securityIdentifier",
|
||||
"trustDirection", NULL};
|
||||
ADS_STATUS status;
|
||||
void *res, *msg;
|
||||
int count, i;
|
||||
@ -1533,11 +1704,31 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
(*names) = talloc(mem_ctx, sizeof(char *) * count);
|
||||
(*alt_names) = talloc(mem_ctx, sizeof(char *) * count);
|
||||
(*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count);
|
||||
if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY);
|
||||
|
||||
for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
|
||||
(*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName");
|
||||
uint32 direction;
|
||||
|
||||
/* direction is a 2 bit bitfield, 1 means they trust us
|
||||
but we don't trust them, so we should not list them
|
||||
as users from that domain can't login */
|
||||
if (ads_pull_uint32(ads, msg, "trustDirection", &direction) &&
|
||||
direction == 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(*names)[i] = ads_pull_string(ads, mem_ctx, msg, "name");
|
||||
(*alt_names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatname");
|
||||
|
||||
if ((*alt_names)[i] && (*alt_names)[i][0]) {
|
||||
/* we prefer the flatname as the primary name
|
||||
for consistency with RPC */
|
||||
char *name = (*alt_names)[i];
|
||||
(*alt_names)[i] = (*names)[i];
|
||||
(*names)[i] = name;
|
||||
}
|
||||
if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) {
|
||||
i++;
|
||||
}
|
||||
@ -1562,7 +1753,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid)
|
||||
void *res;
|
||||
ADS_STATUS rc;
|
||||
|
||||
rc = ads_do_search(ads, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)",
|
||||
rc = ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)",
|
||||
attrs, &res);
|
||||
if (!ADS_ERR_OK(rc)) return rc;
|
||||
if (!ads_pull_sid(ads, res, "objectSid", sid)) {
|
||||
@ -1573,4 +1764,66 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid)
|
||||
return ADS_SUCCESS;
|
||||
}
|
||||
|
||||
/* this is rather complex - we need to find the allternate (netbios) name
|
||||
for the domain, but there isn't a simple query to do this. Instead
|
||||
we look for the principle names on the DCs account and find one that has
|
||||
the right form, then extract the netbios name of the domain from that
|
||||
*/
|
||||
ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup)
|
||||
{
|
||||
char *exp;
|
||||
ADS_STATUS rc;
|
||||
char **principles;
|
||||
char *prefix;
|
||||
int prefix_length;
|
||||
int i;
|
||||
void *res;
|
||||
const char *attrs[] = {"servicePrincipalName", NULL};
|
||||
|
||||
(*workgroup) = NULL;
|
||||
|
||||
asprintf(&exp, "(&(objectclass=computer)(dnshostname=%s.%s))",
|
||||
ads->config.ldap_server_name, ads->config.realm);
|
||||
rc = ads_search(ads, &res, exp, attrs);
|
||||
free(exp);
|
||||
|
||||
if (!ADS_ERR_OK(rc)) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName");
|
||||
|
||||
ads_msgfree(ads, res);
|
||||
|
||||
if (!principles) {
|
||||
return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
|
||||
}
|
||||
|
||||
asprintf(&prefix, "HOST/%s.%s/",
|
||||
ads->config.ldap_server_name,
|
||||
ads->config.realm);
|
||||
|
||||
prefix_length = strlen(prefix);
|
||||
|
||||
for (i=0;principles[i]; i++) {
|
||||
if (strncasecmp(principles[i], prefix, prefix_length) == 0 &&
|
||||
strcasecmp(ads->config.realm, principles[i]+prefix_length) != 0 &&
|
||||
!strchr(principles[i]+prefix_length, '.')) {
|
||||
/* found an alternate (short) name for the domain. */
|
||||
DEBUG(3,("Found alternate name '%s' for realm '%s'\n",
|
||||
principles[i]+prefix_length,
|
||||
ads->config.realm));
|
||||
(*workgroup) = talloc_strdup(mem_ctx, principles[i]+prefix_length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(prefix);
|
||||
|
||||
if (!*workgroup) {
|
||||
return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
|
||||
}
|
||||
|
||||
return ADS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -55,10 +55,10 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user,
|
||||
|
||||
status = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
|
||||
if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->realm)))
|
||||
if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->config.realm)))
|
||||
goto done;
|
||||
if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", name,
|
||||
ads->bind_path)))
|
||||
ads->config.bind_path)))
|
||||
goto done;
|
||||
if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT)))
|
||||
goto done;
|
||||
@ -94,7 +94,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group,
|
||||
status = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
|
||||
if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group,
|
||||
ads->bind_path)))
|
||||
ads->config.bind_path)))
|
||||
goto done;
|
||||
if (!(mods = ads_init_mods(ctx)))
|
||||
goto done;
|
||||
|
@ -77,7 +77,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
|
||||
|
||||
/* we need to fetch a service ticket as the ldap user in the
|
||||
servers realm, regardless of our realm */
|
||||
asprintf(&sname, "ldap/%s@%s", ads->ldap_server_name, ads->server_realm);
|
||||
asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, ads->config.realm);
|
||||
krb5_init_context(&ctx);
|
||||
krb5_set_default_tgs_ktypes(ctx, enc_types);
|
||||
krb5_parse_name(ctx, sname, &principal);
|
||||
@ -163,7 +163,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
|
||||
|
||||
gss_release_buffer(&minor_status, &output_token);
|
||||
|
||||
output_token.value = malloc(strlen(ads->bind_path) + 8);
|
||||
output_token.value = malloc(strlen(ads->config.bind_path) + 8);
|
||||
p = output_token.value;
|
||||
|
||||
*p++ = 1; /* no sign or seal */
|
||||
@ -171,9 +171,10 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
|
||||
*p++ = max_msg_size>>16;
|
||||
*p++ = max_msg_size>>8;
|
||||
*p++ = max_msg_size;
|
||||
snprintf(p, strlen(ads->bind_path)+4, "dn:%s", ads->bind_path);
|
||||
snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
|
||||
p += strlen(ads->config.bind_path);
|
||||
|
||||
output_token.length = strlen(ads->bind_path) + 8;
|
||||
output_token.length = strlen(ads->config.bind_path) + 8;
|
||||
|
||||
gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
|
||||
&output_token, &conf_state,
|
||||
|
@ -39,7 +39,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip
|
||||
new_password = strdup(tmp_password);
|
||||
asprintf(&service_principal, "HOST/%s", host_principal);
|
||||
|
||||
ret = kerberos_set_password(ads->kdc_server, host_principal, password,
|
||||
ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password,
|
||||
service_principal, new_password);
|
||||
|
||||
if (!secrets_store_machine_password(new_password)) {
|
||||
|
@ -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)));
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
|
@ -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)) {
|
||||
|
@ -122,6 +122,7 @@ void kill_async_dns_child(void)
|
||||
{
|
||||
if (child_pid > 0) {
|
||||
kill(child_pid, SIGTERM);
|
||||
child_pid = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,9 +269,8 @@ static BOOL reload_interfaces(time_t t)
|
||||
static BOOL reload_nmbd_services(BOOL test)
|
||||
{
|
||||
BOOL ret;
|
||||
extern fstring remote_machine;
|
||||
|
||||
fstrcpy( remote_machine, "nmbd" );
|
||||
set_remote_machine_name("nmbd");
|
||||
|
||||
if ( lp_loaded() ) {
|
||||
pstring fname;
|
||||
@ -861,8 +860,10 @@ static void usage(char *pname)
|
||||
|
||||
DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
|
||||
|
||||
if ( !open_sockets( is_daemon, global_nmb_port ) )
|
||||
if ( !open_sockets( is_daemon, global_nmb_port ) ) {
|
||||
kill_async_dns_child();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Determine all the IP addresses we have. */
|
||||
load_interfaces();
|
||||
@ -871,6 +872,7 @@ static void usage(char *pname)
|
||||
if( False == create_subnets() )
|
||||
{
|
||||
DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
|
||||
kill_async_dns_child();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -882,6 +884,7 @@ static void usage(char *pname)
|
||||
if( !initialise_wins() )
|
||||
{
|
||||
DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
|
||||
kill_async_dns_child();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -896,6 +899,7 @@ static void usage(char *pname)
|
||||
if( False == register_my_workgroup_and_names() )
|
||||
{
|
||||
DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
|
||||
kill_async_dns_child();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -906,5 +910,6 @@ static void usage(char *pname)
|
||||
|
||||
if (dbf)
|
||||
x_fclose(dbf);
|
||||
kill_async_dns_child();
|
||||
return(0);
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ static void become_domain_master_browser_wins(char *workgroup_name)
|
||||
we can become a domain master browser.
|
||||
*/
|
||||
|
||||
DEBUG(0,("become_domain_master_browser_wins: querying WINS server at IP %s \
|
||||
DEBUG(0,("become_domain_master_browser_wins: querying WINS server from IP %s \
|
||||
for domain master browser name %s on workgroup %s\n",
|
||||
inet_ntoa(unicast_subnet->myip), nmb_namestr(&nmbname), workgroup_name));
|
||||
|
||||
|
@ -225,7 +225,7 @@ void refresh_my_names(time_t t)
|
||||
wins_refresh_name(namerec);
|
||||
}
|
||||
namerec->data.death_time = t + lp_max_ttl();
|
||||
namerec->data.refresh_time = t + MIN(lp_max_ttl(), MAX_REFRESH_TIME);
|
||||
namerec->data.refresh_time = t + MIN(lp_max_ttl()/2, MAX_REFRESH_TIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,17 +106,7 @@ static void register_name_response(struct subnet_record *subrec,
|
||||
success = False;
|
||||
} else {
|
||||
/* Unicast - check to see if the response allows us to have the name. */
|
||||
if(nmb->header.rcode != 0) {
|
||||
/* Error code - we didn't get the name. */
|
||||
success = False;
|
||||
|
||||
DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n",
|
||||
subrec==unicast_subnet?"WINS ":"",
|
||||
inet_ntoa(p->ip),
|
||||
nmb_namestr(answer_name),
|
||||
reg_name,
|
||||
nmb->header.rcode));
|
||||
} else if (nmb->header.opcode == NMB_WACK_OPCODE) {
|
||||
if (nmb->header.opcode == NMB_WACK_OPCODE) {
|
||||
/* WINS server is telling us to wait. Pretend we didn't get
|
||||
the response but don't send out any more register requests. */
|
||||
|
||||
@ -128,6 +118,16 @@ static void register_name_response(struct subnet_record *subrec,
|
||||
rrec->repeat_time = p->timestamp + nmb->answers->ttl;
|
||||
rrec->num_msgs--;
|
||||
return;
|
||||
} else if (nmb->header.rcode != 0) {
|
||||
/* Error code - we didn't get the name. */
|
||||
success = False;
|
||||
|
||||
DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n",
|
||||
subrec==unicast_subnet?"WINS ":"",
|
||||
inet_ntoa(p->ip),
|
||||
nmb_namestr(answer_name),
|
||||
reg_name,
|
||||
nmb->header.rcode));
|
||||
} else {
|
||||
success = True;
|
||||
/* Get the data we need to pass to the success function. */
|
||||
|
@ -705,14 +705,33 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
|
||||
{
|
||||
struct packet_struct *p;
|
||||
struct response_record *rrec;
|
||||
struct in_addr to_ip;
|
||||
|
||||
if(assert_check_subnet(subrec))
|
||||
return NULL;
|
||||
|
||||
to_ip = subrec->bcast_ip;
|
||||
|
||||
/* queries to the WINS server turn up here as queries to IP 0.0.0.0
|
||||
These need to be handled a bit differently */
|
||||
if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
|
||||
/* what we really need to do is loop over each of our wins
|
||||
* servers and wins server tags here, but that just doesn't
|
||||
* fit our architecture at the moment (userdata may already
|
||||
* be used when we get here). For now we just query the first
|
||||
* active wins server on the first tag. */
|
||||
char **tags = wins_srv_tags();
|
||||
if (!tags) {
|
||||
return NULL;
|
||||
}
|
||||
to_ip = wins_srv_ip_tag(tags[0], to_ip);
|
||||
wins_srv_tags_free(tags);
|
||||
}
|
||||
|
||||
if(( p = create_and_init_netbios_packet(nmbname,
|
||||
(subrec != unicast_subnet),
|
||||
(subrec == unicast_subnet),
|
||||
subrec->bcast_ip)) == NULL)
|
||||
to_ip)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if(lp_bind_interfaces_only()) {
|
||||
@ -1670,7 +1689,7 @@ void retransmit_or_expire_response_records(time_t t)
|
||||
to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
|
||||
subrec->subnet_name));
|
||||
}
|
||||
rrec->repeat_time += rrec->repeat_interval;
|
||||
rrec->repeat_time = t + rrec->repeat_interval;
|
||||
rrec->repeat_count--;
|
||||
}
|
||||
else
|
||||
@ -1950,7 +1969,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
|
||||
/* 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,23 + len,True);
|
||||
memcpy(ptr,tmp,4);
|
||||
|
||||
SCVAL(ptr,smb_com,SMBtrans);
|
||||
|
@ -4,6 +4,8 @@
|
||||
Copyright (C) Andrew Tridgell 1994-1998
|
||||
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
|
||||
Copyright (C) Jeremy Allison 1994-1998
|
||||
Copyright (C) Jim McDonough 2002
|
||||
Copyright (C) Anthony Liguori 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
|
||||
@ -284,19 +286,108 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
|
||||
/* Construct reply. */
|
||||
|
||||
q = outbuf;
|
||||
if (SVAL(uniuser, 0) == 0) {
|
||||
SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
|
||||
} else {
|
||||
SSVAL(q, 0, SAMLOGON_R);
|
||||
}
|
||||
q += 2;
|
||||
/* we want the simple version unless we are an ADS PDC..which means */
|
||||
/* never, at least for now */
|
||||
if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) {
|
||||
if (SVAL(uniuser, 0) == 0) {
|
||||
SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
|
||||
} else {
|
||||
SSVAL(q, 0, SAMLOGON_R);
|
||||
}
|
||||
|
||||
q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
|
||||
q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
|
||||
q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True);
|
||||
q += 2;
|
||||
|
||||
q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
|
||||
q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
|
||||
q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True);
|
||||
}
|
||||
#ifdef HAVE_ADS
|
||||
else {
|
||||
GUID domain_guid;
|
||||
pstring domain;
|
||||
char *component, *dc, *q1;
|
||||
uint8 size;
|
||||
|
||||
safe_strcpy(domain, lp_realm(), sizeof(domain));
|
||||
|
||||
if (SVAL(uniuser, 0) == 0) {
|
||||
SSVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
|
||||
} else {
|
||||
SSVAL(q, 0, SAMLOGON_AD_R);
|
||||
}
|
||||
q += 2;
|
||||
|
||||
SSVAL(q, 0, 0);
|
||||
q += 2;
|
||||
SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS|
|
||||
ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE);
|
||||
q += 4;
|
||||
|
||||
/* Push Domain GUID */
|
||||
if (False == secrets_fetch_domain_guid(domain, &domain_guid)) {
|
||||
DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain));
|
||||
return;
|
||||
}
|
||||
memcpy(q, &domain_guid, sizeof(domain_guid));
|
||||
q += sizeof(domain_guid);
|
||||
|
||||
/* Push domain components */
|
||||
dc = domain;
|
||||
q1 = q;
|
||||
while ((component = strsep(&dc, "."))) {
|
||||
size = push_ascii(&q[1], component, -1, 0);
|
||||
SCVAL(q, 0, size);
|
||||
q += (size + 1);
|
||||
}
|
||||
SCVAL(q, 0, 0); q++;
|
||||
SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
|
||||
q += 2; /* it must follow the domain name. */
|
||||
|
||||
/* Push dns host name */
|
||||
size = push_ascii(&q[1], global_myname, -1, 0);
|
||||
SCVAL(q, 0, size);
|
||||
q += (size + 1);
|
||||
SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
|
||||
q += 2; /* it must follow the domain name. */
|
||||
|
||||
/* Push NETBIOS of domain */
|
||||
size = push_ascii(&q[1], domain, -1, STR_UPPER);
|
||||
SCVAL(q, 0, size);
|
||||
q += (size + 1);
|
||||
SCVAL(q, 0, 0); q++; /* is this a null terminator or empty field */
|
||||
/* null terminator would not be needed because size is included */
|
||||
|
||||
/* Push NETBIOS of hostname */
|
||||
size = push_ascii(&q[1], my_name, -1, 0);
|
||||
SCVAL(q, 0, size);
|
||||
q += (size + 1);
|
||||
SCVAL(q, 0, 0); q++; /* null terminator or empty field? */
|
||||
|
||||
/* Push user account */
|
||||
size = push_ascii(&q[1], ascuser, -1, 0);
|
||||
SCVAL(q, 0, size);
|
||||
q += (size + 1);
|
||||
|
||||
/* Push 'Default-First-Site-Name' */
|
||||
size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0);
|
||||
SCVAL(q, 0, size);
|
||||
q += (size + 1);
|
||||
|
||||
SSVAL(q, 0, 0xc000); /* unknown */
|
||||
SCVAL(q, 2, PTR_DIFF(q,q1));
|
||||
SCVAL(q, 3, 0x10); /* unknown */
|
||||
q += 4;
|
||||
|
||||
SIVAL(q, 0, 0x00000002); q += 4; /* unknown */
|
||||
SIVAL(q, 0, (iface_ip(p->ip))->s_addr); q += 4;
|
||||
SIVAL(q, 0, 0x00000000); q += 4; /* unknown */
|
||||
SIVAL(q, 0, 0x00000000); q += 4; /* unknown */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* tell the client what version we are */
|
||||
SIVAL(q, 0, 1); /* our ntversion */
|
||||
SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13);
|
||||
/* our ntversion */
|
||||
SSVAL(q, 4, 0xffff); /* our lmnttoken */
|
||||
SSVAL(q, 6, 0xffff); /* our lm20token */
|
||||
q += 8;
|
||||
|
@ -79,7 +79,7 @@ static int converse(pam_handle_t *pamh, int nargs,
|
||||
}
|
||||
|
||||
|
||||
int _make_remark(pam_handle_t * pamh, int type, const char *text)
|
||||
static int _make_remark(pam_handle_t * pamh, int type, const char *text)
|
||||
{
|
||||
int retval = PAM_SUCCESS;
|
||||
|
||||
@ -163,6 +163,10 @@ static int winbind_auth_request(const char *user, const char *pass, int ctrl)
|
||||
/* password expired */
|
||||
_pam_log(LOG_WARNING, "user `%s' password expired", user);
|
||||
return retval;
|
||||
case PAM_NEW_AUTHTOK_REQD:
|
||||
/* password expired */
|
||||
_pam_log(LOG_WARNING, "user `%s' new password required", user);
|
||||
return retval;
|
||||
case PAM_USER_UNKNOWN:
|
||||
/* the user does not exist */
|
||||
if (ctrl & WINBIND_DEBUG_ARG)
|
||||
@ -241,12 +245,12 @@ static char *_pam_delete(register char *xx)
|
||||
* obtain a password from the user
|
||||
*/
|
||||
|
||||
int _winbind_read_password(pam_handle_t * pamh
|
||||
,unsigned int ctrl
|
||||
,const char *comment
|
||||
,const char *prompt1
|
||||
,const char *prompt2
|
||||
,const char **pass)
|
||||
static int _winbind_read_password(pam_handle_t * pamh
|
||||
,unsigned int ctrl
|
||||
,const char *comment
|
||||
,const char *prompt1
|
||||
,const char *prompt2
|
||||
,const char **pass)
|
||||
{
|
||||
int authtok_flag;
|
||||
int retval;
|
||||
|
@ -65,7 +65,7 @@ BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
|
||||
|
||||
/* Call winbindd to convert sid to name */
|
||||
|
||||
BOOL winbind_lookup_sid(DOM_SID *sid,
|
||||
BOOL winbind_lookup_sid(const DOM_SID *sid,
|
||||
fstring dom_name, fstring name,
|
||||
enum SID_NAME_USE *name_type)
|
||||
{
|
||||
@ -102,7 +102,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid,
|
||||
|
||||
/* Call winbindd to convert SID to uid */
|
||||
|
||||
BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid)
|
||||
BOOL winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
|
||||
{
|
||||
struct winbindd_request request;
|
||||
struct winbindd_response response;
|
||||
@ -168,7 +168,7 @@ BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
|
||||
|
||||
/* Call winbindd to convert SID to gid */
|
||||
|
||||
BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid)
|
||||
BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
|
||||
{
|
||||
struct winbindd_request request;
|
||||
struct winbindd_response response;
|
||||
|
@ -28,7 +28,6 @@
|
||||
/* Global variables. These are effectively the client state information */
|
||||
|
||||
int winbindd_fd = -1; /* fd for winbindd socket */
|
||||
static char *excluded_domain;
|
||||
|
||||
/* Free a response structure */
|
||||
|
||||
@ -40,16 +39,6 @@ void free_response(struct winbindd_response *response)
|
||||
SAFE_FREE(response->extra_data);
|
||||
}
|
||||
|
||||
/*
|
||||
smbd needs to be able to exclude lookups for its own domain
|
||||
*/
|
||||
void winbind_exclude_domain(const char *domain)
|
||||
{
|
||||
SAFE_FREE(excluded_domain);
|
||||
excluded_domain = strdup(domain);
|
||||
}
|
||||
|
||||
|
||||
/* Initialise a request structure */
|
||||
|
||||
void init_request(struct winbindd_request *request, int request_type)
|
||||
@ -325,12 +314,6 @@ NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
/* smbd may have excluded this domain */
|
||||
if (excluded_domain &&
|
||||
strcasecmp(excluded_domain, request->domain) == 0) {
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
if (!request) {
|
||||
ZERO_STRUCT(lrequest);
|
||||
request = &lrequest;
|
||||
|
@ -255,8 +255,7 @@ static BOOL wbinfo_check_secret(void)
|
||||
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response) ==
|
||||
NSS_STATUS_SUCCESS;
|
||||
result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response);
|
||||
|
||||
d_printf("checking the trust secret via RPC calls %s\n",
|
||||
(result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
|
||||
@ -490,9 +489,9 @@ static BOOL wbinfo_auth_crap(char *username)
|
||||
|
||||
generate_random_buffer(request.data.auth_crap.chal, 8, False);
|
||||
|
||||
SMBencrypt((uchar *)pass, request.data.auth_crap.chal,
|
||||
SMBencrypt(pass, request.data.auth_crap.chal,
|
||||
(uchar *)request.data.auth_crap.lm_resp);
|
||||
SMBNTencrypt((uchar *)pass, request.data.auth_crap.chal,
|
||||
SMBNTencrypt(pass, request.data.auth_crap.chal,
|
||||
(uchar *)request.data.auth_crap.nt_resp);
|
||||
|
||||
request.data.auth_crap.lm_resp_len = 24;
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
/* List of all connected clients */
|
||||
|
||||
struct winbindd_cli_state *client_list;
|
||||
static struct winbindd_cli_state *client_list;
|
||||
static int num_clients;
|
||||
BOOL opt_nocache = False;
|
||||
BOOL opt_dual_daemon = False;
|
||||
@ -375,6 +375,9 @@ void winbind_process_packet(struct winbindd_cli_state *state)
|
||||
{
|
||||
/* Process request */
|
||||
|
||||
/* Ensure null termination of entire request */
|
||||
state->request.domain[sizeof(state->request.domain)-1]='\0';
|
||||
|
||||
state->pid = state->request.pid;
|
||||
|
||||
process_request(state);
|
||||
@ -688,6 +691,8 @@ int winbind_setup_common(void)
|
||||
|
||||
}
|
||||
|
||||
namecache_enable(); /* Enable netbios namecache */
|
||||
|
||||
/* Get list of domains we look up requests for. This includes the
|
||||
domain which we are a member of as well as any trusted
|
||||
domains. */
|
||||
|
@ -88,7 +88,7 @@ typedef struct {
|
||||
|
||||
struct winbindd_domain {
|
||||
fstring name; /* Domain name */
|
||||
fstring full_name; /* full Domain name (realm) */
|
||||
fstring alt_name; /* alt Domain name (if any) */
|
||||
DOM_SID sid; /* SID for this domain */
|
||||
|
||||
/* Lookup methods for this domain (LDAP or RPC) */
|
||||
@ -170,11 +170,15 @@ struct winbindd_methods {
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint32 *num_domains,
|
||||
char ***names,
|
||||
char ***alt_names,
|
||||
DOM_SID **dom_sids);
|
||||
|
||||
/* find the domain sid */
|
||||
NTSTATUS (*domain_sid)(struct winbindd_domain *domain,
|
||||
DOM_SID *sid);
|
||||
|
||||
/* setup the list of alternate names for the domain, if any */
|
||||
NTSTATUS (*alternate_name)(struct winbindd_domain *domain);
|
||||
};
|
||||
|
||||
/* Used to glue a policy handle and cli_state together */
|
||||
@ -190,6 +194,8 @@ typedef struct {
|
||||
#include "rpc_client.h"
|
||||
|
||||
#define WINBINDD_ESTABLISH_LOOP 30
|
||||
#define WINBINDD_RESCAN_FREQ 300
|
||||
|
||||
#define DOM_SEQUENCE_NONE ((uint32)-1)
|
||||
|
||||
/* SETENV */
|
||||
|
@ -61,8 +61,8 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope
|
||||
|
||||
if (*res) ads_msgfree(ads, *res);
|
||||
*res = NULL;
|
||||
DEBUG(3,("Reopening ads connection to %s after error %s\n",
|
||||
ads->ldap_server, ads_errstr(status)));
|
||||
DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n",
|
||||
ads->config.realm, ads_errstr(status)));
|
||||
if (ads->ld) {
|
||||
ldap_unbind(ads->ld);
|
||||
}
|
||||
@ -87,7 +87,7 @@ ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
|
||||
const char *exp,
|
||||
const char **attrs)
|
||||
{
|
||||
return ads_do_search_retry(ads, ads->bind_path, LDAP_SCOPE_SUBTREE,
|
||||
return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
|
||||
exp, attrs, res);
|
||||
}
|
||||
|
||||
@ -108,8 +108,6 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
|
||||
ADS_STRUCT *ads;
|
||||
ADS_STATUS status;
|
||||
char *ccache;
|
||||
struct in_addr server_ip;
|
||||
char *sname;
|
||||
|
||||
if (domain->private) {
|
||||
return (ADS_STRUCT *)domain->private;
|
||||
@ -120,30 +118,23 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
|
||||
SETENV("KRB5CCNAME", ccache, 1);
|
||||
unlink(ccache);
|
||||
|
||||
if (resolve_name(domain->name, &server_ip, 0x1b)) {
|
||||
sname = inet_ntoa(server_ip);
|
||||
} else if (resolve_name(domain->name, &server_ip, 0x1c)) {
|
||||
sname = inet_ntoa(server_ip);
|
||||
} else {
|
||||
if (strcasecmp(domain->name, lp_workgroup()) != 0) {
|
||||
DEBUG(1,("can't find domain controller for %s\n", domain->name));
|
||||
return NULL;
|
||||
}
|
||||
sname = NULL;
|
||||
}
|
||||
|
||||
ads = ads_init(primary_realm, domain->name, NULL, NULL, NULL);
|
||||
ads = ads_init(domain->alt_name, domain->name, NULL);
|
||||
if (!ads) {
|
||||
DEBUG(1,("ads_init for domain %s failed\n", domain->name));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* the machine acct password might have change - fetch it every time */
|
||||
SAFE_FREE(ads->password);
|
||||
ads->password = secrets_fetch_machine_password();
|
||||
SAFE_FREE(ads->auth.password);
|
||||
ads->auth.password = secrets_fetch_machine_password();
|
||||
|
||||
if (primary_realm) {
|
||||
SAFE_FREE(ads->auth.realm);
|
||||
ads->auth.realm = strdup(primary_realm);
|
||||
}
|
||||
|
||||
status = ads_connect(ads);
|
||||
if (!ADS_ERR_OK(status) || !ads->realm) {
|
||||
if (!ADS_ERR_OK(status) || !ads->config.realm) {
|
||||
extern struct winbindd_methods msrpc_methods;
|
||||
DEBUG(1,("ads_connect for domain %s failed: %s\n",
|
||||
domain->name, ads_errstr(status)));
|
||||
@ -161,11 +152,9 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
|
||||
|
||||
/* remember our primary realm for trusted domain support */
|
||||
if (!primary_realm) {
|
||||
primary_realm = strdup(ads->realm);
|
||||
primary_realm = strdup(ads->config.realm);
|
||||
}
|
||||
|
||||
fstrcpy(domain->full_name, ads->server_realm);
|
||||
|
||||
domain->private = (void *)ads;
|
||||
return ads;
|
||||
}
|
||||
@ -405,7 +394,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
|
||||
/* accept either the win2000 or the pre-win2000 username */
|
||||
asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
|
||||
name, name, ads->realm);
|
||||
name, name, ads->config.realm);
|
||||
rc = ads_search_retry(ads, &res, exp, attrs);
|
||||
free(exp);
|
||||
if (!ADS_ERR_OK(rc)) {
|
||||
@ -535,49 +524,6 @@ failed:
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
/* convert a sid to a distnguished name */
|
||||
static NTSTATUS sid_to_distinguished_name(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
DOM_SID *sid,
|
||||
char **dn)
|
||||
{
|
||||
ADS_STRUCT *ads = NULL;
|
||||
const char *attrs[] = {"distinguishedName", NULL};
|
||||
ADS_STATUS rc;
|
||||
void *msg = NULL;
|
||||
char *exp;
|
||||
char *sidstr;
|
||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
DEBUG(3,("ads: sid_to_distinguished_name\n"));
|
||||
|
||||
ads = ads_cached_connection(domain);
|
||||
if (!ads) goto done;
|
||||
|
||||
sidstr = sid_binstring(sid);
|
||||
asprintf(&exp, "(objectSid=%s)", sidstr);
|
||||
rc = ads_search_retry(ads, &msg, exp, attrs);
|
||||
free(exp);
|
||||
free(sidstr);
|
||||
if (!ADS_ERR_OK(rc)) {
|
||||
DEBUG(1,("sid_to_distinguished_name ads_search: %s\n", ads_errstr(rc)));
|
||||
goto done;
|
||||
}
|
||||
|
||||
*dn = ads_pull_string(ads, mem_ctx, msg, "distinguishedName");
|
||||
|
||||
status = NT_STATUS_OK;
|
||||
|
||||
DEBUG(3,("ads sid_to_distinguished_name mapped %s\n", *dn));
|
||||
|
||||
done:
|
||||
if (msg) ads_msgfree(ads, msg);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Lookup user information from a rid */
|
||||
static NTSTATUS query_user(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
@ -831,6 +777,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint32 *num_domains,
|
||||
char ***names,
|
||||
char ***alt_names,
|
||||
DOM_SID **dom_sids)
|
||||
{
|
||||
ADS_STRUCT *ads;
|
||||
@ -842,7 +789,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
|
||||
ads = ads_cached_connection(domain);
|
||||
if (!ads) return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, dom_sids);
|
||||
rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, alt_names, dom_sids);
|
||||
|
||||
return ads_ntstatus(rc);
|
||||
}
|
||||
@ -867,6 +814,37 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
|
||||
return ads_ntstatus(rc);
|
||||
}
|
||||
|
||||
|
||||
/* find alternate names list for the domain - for ADS this is the
|
||||
netbios name */
|
||||
static NTSTATUS alternate_name(struct winbindd_domain *domain)
|
||||
{
|
||||
ADS_STRUCT *ads;
|
||||
ADS_STATUS rc;
|
||||
TALLOC_CTX *ctx;
|
||||
char *workgroup;
|
||||
|
||||
ads = ads_cached_connection(domain);
|
||||
if (!ads) return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
if (!(ctx = talloc_init_named("alternate_name"))) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
rc = ads_workgroup_name(ads, ctx, &workgroup);
|
||||
|
||||
if (ADS_ERR_OK(rc)) {
|
||||
fstrcpy(domain->name, workgroup);
|
||||
fstrcpy(domain->alt_name, ads->config.realm);
|
||||
strupper(domain->alt_name);
|
||||
strupper(domain->name);
|
||||
}
|
||||
|
||||
talloc_destroy(ctx);
|
||||
|
||||
return ads_ntstatus(rc);
|
||||
}
|
||||
|
||||
/* the ADS backend methods are exposed via this structure */
|
||||
struct winbindd_methods ads_methods = {
|
||||
True,
|
||||
@ -879,7 +857,8 @@ struct winbindd_methods ads_methods = {
|
||||
lookup_groupmem,
|
||||
sequence_number,
|
||||
trusted_domains,
|
||||
domain_sid
|
||||
domain_sid,
|
||||
alternate_name
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -873,13 +873,14 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint32 *num_domains,
|
||||
char ***names,
|
||||
char ***alt_names,
|
||||
DOM_SID **dom_sids)
|
||||
{
|
||||
struct winbind_cache *cache = get_cache(domain);
|
||||
|
||||
/* we don't cache this call */
|
||||
return cache->backend->trusted_domains(domain, mem_ctx, num_domains,
|
||||
names, dom_sids);
|
||||
names, alt_names, dom_sids);
|
||||
}
|
||||
|
||||
/* find the domain sid */
|
||||
@ -891,6 +892,15 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
|
||||
return cache->backend->domain_sid(domain, sid);
|
||||
}
|
||||
|
||||
/* find the alternate names for the domain, if any */
|
||||
static NTSTATUS alternate_name(struct winbindd_domain *domain)
|
||||
{
|
||||
struct winbind_cache *cache = get_cache(domain);
|
||||
|
||||
/* we don't cache this call */
|
||||
return cache->backend->alternate_name(domain);
|
||||
}
|
||||
|
||||
/* the ADS backend methods are exposed via this structure */
|
||||
struct winbindd_methods cache_methods = {
|
||||
True,
|
||||
@ -903,5 +913,6 @@ struct winbindd_methods cache_methods = {
|
||||
lookup_groupmem,
|
||||
sequence_number,
|
||||
trusted_domains,
|
||||
domain_sid
|
||||
domain_sid,
|
||||
alternate_name
|
||||
};
|
||||
|
@ -90,12 +90,122 @@ struct get_dc_name_cache {
|
||||
struct get_dc_name_cache *prev, *next;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
find the DC for a domain using methods appropriate for a ADS domain
|
||||
*/
|
||||
static BOOL cm_ads_find_dc(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.no_bind = 1;
|
||||
|
||||
DEBUG(4,("cm_ads_find_dc: 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,("cm_ads_find_dc: using server='%s' IP=%s\n",
|
||||
srv_name, inet_ntoa(*dc_ip)));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
find the DC for a domain using methods appropriate for a RPC domain
|
||||
*/
|
||||
static BOOL cm_rpc_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
|
||||
{
|
||||
struct in_addr *ip_list = NULL;
|
||||
int count, i;
|
||||
|
||||
/* Lookup domain controller name. Try the real PDC first to avoid
|
||||
SAM sync delays */
|
||||
if (!get_dc_list(True, domain, &ip_list, &count)) {
|
||||
if (!get_dc_list(False, domain, &ip_list, &count)) {
|
||||
DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pick a nice close server */
|
||||
/* Look for DC on local net */
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!is_local_net(ip_list[i]))
|
||||
continue;
|
||||
|
||||
if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
|
||||
*dc_ip = ip_list[i];
|
||||
SAFE_FREE(ip_list);
|
||||
return True;
|
||||
}
|
||||
zero_ip(&ip_list[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Secondly try and contact a random PDC/BDC.
|
||||
*/
|
||||
|
||||
i = (sys_random() % count);
|
||||
|
||||
if (!is_zero_ip(ip_list[i]) &&
|
||||
name_status_find(domain, 0x1c, 0x20,
|
||||
ip_list[i], srv_name)) {
|
||||
*dc_ip = ip_list[i];
|
||||
SAFE_FREE(ip_list);
|
||||
return True;
|
||||
}
|
||||
zero_ip(&ip_list[i]); /* Tried and failed. */
|
||||
|
||||
/* Finally return first DC that we can contact using a node
|
||||
status */
|
||||
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];
|
||||
SAFE_FREE(ip_list);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE(ip_list);
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
|
||||
{
|
||||
static struct get_dc_name_cache *get_dc_name_cache;
|
||||
struct get_dc_name_cache *dcc;
|
||||
struct in_addr *ip_list, dc_ip;
|
||||
int count, i;
|
||||
struct in_addr dc_ip;
|
||||
BOOL ret;
|
||||
|
||||
/* Check the cache for previous lookups */
|
||||
|
||||
@ -144,66 +254,22 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr
|
||||
|
||||
DLIST_ADD(get_dc_name_cache, dcc);
|
||||
|
||||
/* Lookup domain controller name. Try the real PDC first to avoid
|
||||
SAM sync delays */
|
||||
if (!get_dc_list(True, domain, &ip_list, &count)) {
|
||||
if (!get_dc_list(False, domain, &ip_list, &count)) {
|
||||
DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
|
||||
return False;
|
||||
}
|
||||
zero_ip(&dc_ip);
|
||||
|
||||
ret = False;
|
||||
if (lp_security() == SEC_ADS) {
|
||||
ret = cm_ads_find_dc(domain, &dc_ip, srv_name);
|
||||
}
|
||||
if (!ret) {
|
||||
/* fall back on rpc methods if the ADS methods fail */
|
||||
ret = cm_rpc_find_dc(domain, &dc_ip, srv_name);
|
||||
}
|
||||
|
||||
/* Pick a nice close server */
|
||||
/* Look for DC on local net */
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!is_local_net(ip_list[i]))
|
||||
continue;
|
||||
|
||||
if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
|
||||
dc_ip = ip_list[i];
|
||||
goto done;
|
||||
}
|
||||
zero_ip(&ip_list[i]);
|
||||
if (!ret) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
* Secondly try and contact a random PDC/BDC.
|
||||
*/
|
||||
|
||||
i = (sys_random() % count);
|
||||
|
||||
if (!is_zero_ip(ip_list[i]) &&
|
||||
name_status_find(domain, 0x1c, 0x20,
|
||||
ip_list[i], srv_name)) {
|
||||
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;
|
||||
|
||||
if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
|
||||
dc_ip = ip_list[i];
|
||||
goto 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. */
|
||||
|
||||
/* We have a name so make the cache entry positive now */
|
||||
|
||||
fstrcpy(dcc->srv_name, srv_name);
|
||||
|
||||
DEBUG(3, ("cm_get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
|
||||
@ -211,8 +277,6 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr
|
||||
|
||||
*ip_out = dc_ip;
|
||||
|
||||
SAFE_FREE(ip_list);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -262,11 +326,23 @@ static struct failed_connection_cache *failed_connection_cache;
|
||||
|
||||
/* Add an entry to the failed conneciton cache */
|
||||
|
||||
static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn, NTSTATUS result) {
|
||||
static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn,
|
||||
NTSTATUS result)
|
||||
{
|
||||
struct failed_connection_cache *fcc;
|
||||
|
||||
SMB_ASSERT(!NT_STATUS_IS_OK(result));
|
||||
|
||||
/* Check we already aren't in the cache */
|
||||
|
||||
for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
|
||||
if (strequal(fcc->domain_name, new_conn->domain)) {
|
||||
DEBUG(10, ("domain %s already tried and failed\n",
|
||||
fcc->domain_name));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create negative lookup cache entry for this domain and controller */
|
||||
|
||||
if (!(fcc = (struct failed_connection_cache *)
|
||||
@ -794,7 +870,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
|
||||
return result;
|
||||
}
|
||||
|
||||
result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
|
||||
result = cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
|
||||
SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
@ -808,7 +884,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
|
||||
}
|
||||
|
||||
/* Try again */
|
||||
result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
|
||||
result = cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
|
||||
SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
|
||||
}
|
||||
|
||||
|
@ -196,6 +196,9 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
|
||||
gid_t gid;
|
||||
int gr_mem_len;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';
|
||||
|
||||
DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid,
|
||||
state->request.data.groupname));
|
||||
|
||||
@ -783,6 +786,9 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
|
||||
int i;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.username[sizeof(state->request.data.username)-1]='\0';
|
||||
|
||||
DEBUG(3, ("[%5d]: getgroups %s\n", state->pid,
|
||||
state->request.data.username));
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
/* Update this when you change the interface. */
|
||||
|
||||
#define WINBIND_INTERFACE_VERSION 4
|
||||
#define WINBIND_INTERFACE_VERSION 5
|
||||
|
||||
/* Socket commands */
|
||||
|
||||
@ -107,6 +107,12 @@ enum winbindd_cmd {
|
||||
WINBINDD_NUM_CMDS
|
||||
};
|
||||
|
||||
#define WINBIND_PAM_INFO3_NDR 0x0001
|
||||
#define WINBIND_PAM_INFO3_TEXT 0x0002
|
||||
#define WINBIND_PAM_NTKEY 0x0004
|
||||
#define WINBIND_PAM_LMKEY 0x0008
|
||||
#define WINBIND_PAM_CONTACT_TRUSTDOM 0x0010
|
||||
|
||||
/* Winbind request structure */
|
||||
|
||||
struct winbindd_request {
|
||||
@ -132,6 +138,8 @@ struct winbindd_request {
|
||||
uint16 lm_resp_len;
|
||||
fstring nt_resp;
|
||||
uint16 nt_resp_len;
|
||||
fstring workstation;
|
||||
uint32 flags;
|
||||
} auth_crap;
|
||||
struct {
|
||||
fstring user;
|
||||
@ -216,6 +224,8 @@ struct winbindd_response {
|
||||
fstring nt_status_string;
|
||||
fstring error_string;
|
||||
int pam_error;
|
||||
char nt_session_key[16];
|
||||
char first_8_lm_hash[8];
|
||||
} auth;
|
||||
} data;
|
||||
|
||||
|
@ -23,17 +23,41 @@
|
||||
*/
|
||||
|
||||
#include "winbindd.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_WINBIND
|
||||
|
||||
|
||||
static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
|
||||
struct winbindd_cli_state *state,
|
||||
NET_USER_INFO_3 *info3)
|
||||
{
|
||||
prs_struct ps;
|
||||
uint32 size;
|
||||
if (!prs_init(&ps, 256 /* Random, non-zero number */, mem_ctx, MARSHALL)) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (!net_io_user_info3("", info3, &ps, 1, 3)) {
|
||||
prs_mem_free(&ps);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
size = prs_data_size(&ps);
|
||||
state->response.extra_data = memdup(prs_data_p(&ps), size);
|
||||
if (!state->response.extra_data) {
|
||||
prs_mem_free(&ps);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
state->response.length += size;
|
||||
prs_mem_free(&ps);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Return a password structure from a username. */
|
||||
|
||||
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
{
|
||||
NTSTATUS result;
|
||||
fstring name_domain, name_user;
|
||||
int passlen;
|
||||
unsigned char trust_passwd[16];
|
||||
time_t last_change_time;
|
||||
uint32 smb_uid_low;
|
||||
@ -46,6 +70,12 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
|
||||
extern pstring global_myname;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.auth.pass[sizeof(state->request.data.auth.pass)-1]='\0';
|
||||
|
||||
DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
|
||||
state->request.data.auth.user));
|
||||
|
||||
@ -64,16 +94,14 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
goto done;
|
||||
}
|
||||
|
||||
passlen = strlen(state->request.data.auth.pass);
|
||||
|
||||
{
|
||||
unsigned char local_lm_response[24];
|
||||
unsigned char local_nt_response[24];
|
||||
|
||||
generate_random_buffer(chal, 8, False);
|
||||
SMBencrypt( (const uchar *)state->request.data.auth.pass, chal, local_lm_response);
|
||||
SMBencrypt(state->request.data.auth.pass, chal, local_lm_response);
|
||||
|
||||
SMBNTencrypt((const uchar *)state->request.data.auth.pass, chal, local_nt_response);
|
||||
SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response);
|
||||
|
||||
lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response));
|
||||
nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response));
|
||||
@ -140,34 +168,67 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
NET_USER_INFO_3 info3;
|
||||
struct cli_state *cli = NULL;
|
||||
TALLOC_CTX *mem_ctx = NULL;
|
||||
const char *domain = NULL;
|
||||
char *user = NULL;
|
||||
char *domain = NULL;
|
||||
char *contact_domain;
|
||||
char *workstation;
|
||||
|
||||
DATA_BLOB lm_resp, nt_resp;
|
||||
|
||||
extern pstring global_myname;
|
||||
|
||||
DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
|
||||
state->request.data.auth_crap.domain, state->request.data.auth_crap.user));
|
||||
/* Ensure null termination */
|
||||
state->request.data.auth_crap.user[sizeof(state->request.data.auth_crap.user)-1]='\0';
|
||||
|
||||
if (!(mem_ctx = talloc_init_named("winbind pam auth crap for %s", state->request.data.auth.user))) {
|
||||
/* Ensure null termination */
|
||||
state->request.data.auth_crap.domain[sizeof(state->request.data.auth_crap.domain)-1]='\0';
|
||||
|
||||
if (!(mem_ctx = talloc_init_named("winbind pam auth crap for (utf8) %s", state->request.data.auth.user))) {
|
||||
DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n"));
|
||||
result = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (pull_utf8_talloc(mem_ctx, &user, state->request.data.auth_crap.user) < 0) {
|
||||
DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
|
||||
}
|
||||
|
||||
if (*state->request.data.auth_crap.domain) {
|
||||
domain = talloc_strdup(mem_ctx, state->request.data.auth_crap.domain);
|
||||
if (pull_utf8_talloc(mem_ctx, &domain, state->request.data.auth_crap.domain) < 0) {
|
||||
DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
|
||||
}
|
||||
} else if (lp_winbind_use_default_domain()) {
|
||||
domain = talloc_strdup(mem_ctx, lp_workgroup());
|
||||
domain = lp_workgroup();
|
||||
} else {
|
||||
DEBUG(5,("no domain specified with username (%s) - failing auth\n", state->request.data.auth.user));
|
||||
DEBUG(5,("no domain specified with username (%s) - failing auth\n",
|
||||
user));
|
||||
result = NT_STATUS_INVALID_PARAMETER;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!domain) {
|
||||
DEBUG(0,("winbindd_pam_auth_crap: talloc_strdup failed!\n"));
|
||||
result = NT_STATUS_NO_MEMORY;
|
||||
DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
|
||||
domain, user));
|
||||
|
||||
if (lp_allow_trusted_domains() && (state->request.data.auth_crap.flags & WINBIND_PAM_CONTACT_TRUSTDOM)) {
|
||||
contact_domain = domain;
|
||||
} else {
|
||||
contact_domain = lp_workgroup();
|
||||
}
|
||||
|
||||
if (*state->request.data.auth_crap.workstation) {
|
||||
if (pull_utf8_talloc(mem_ctx, &workstation, state->request.data.auth_crap.workstation) < 0) {
|
||||
DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
|
||||
}
|
||||
} else {
|
||||
workstation = global_myname;
|
||||
}
|
||||
|
||||
if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp)
|
||||
|| state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) {
|
||||
DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
|
||||
state->request.data.auth_crap.lm_resp_len,
|
||||
state->request.data.auth_crap.nt_resp_len));
|
||||
result = NT_STATUS_INVALID_PARAMETER;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -175,13 +236,15 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len);
|
||||
|
||||
/*
|
||||
* Get the machine account password for our primary domain
|
||||
* Get the machine account password for the domain to contact.
|
||||
* This is either our own domain for a workstation, or possibly
|
||||
* any domain for a PDC with trusted domains.
|
||||
*/
|
||||
|
||||
if (!secrets_fetch_trust_account_password(
|
||||
lp_workgroup(), trust_passwd, &last_change_time)) {
|
||||
if (!secrets_fetch_trust_account_password (
|
||||
contact_domain, trust_passwd, &last_change_time)) {
|
||||
DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
|
||||
"password for domain %s\n", lp_workgroup()));
|
||||
"password for domain %s\n", contact_domain));
|
||||
result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
goto done;
|
||||
}
|
||||
@ -189,7 +252,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
ZERO_STRUCT(info3);
|
||||
|
||||
/* Don't shut this down - it belongs to the connection cache code */
|
||||
result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
|
||||
result = cm_get_netlogon_cli(contact_domain, trust_passwd, &cli);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", nt_errstr(result)));
|
||||
@ -197,27 +260,43 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
}
|
||||
|
||||
result = cli_netlogon_sam_network_logon(cli, mem_ctx,
|
||||
state->request.data.auth_crap.user, domain,
|
||||
global_myname, state->request.data.auth_crap.chal,
|
||||
user, domain,
|
||||
workstation, state->request.data.auth_crap.chal,
|
||||
lm_resp, nt_resp,
|
||||
&info3);
|
||||
|
||||
if (NT_STATUS_IS_OK(result)) {
|
||||
uni_group_cache_store_netlogon(mem_ctx, &info3);
|
||||
if (state->request.data.auth_crap.flags & WINBIND_PAM_INFO3_NDR) {
|
||||
result = append_info3_as_ndr(mem_ctx, state, &info3);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* we don't currently do this stuff right */
|
||||
if (state->request.data.auth_crap.flags & WINBIND_PAM_NTKEY) {
|
||||
SMB_ASSERT(sizeof(state->response.data.auth.nt_session_key) == sizeof(info3.user_sess_key));
|
||||
memcpy(state->response.data.auth.nt_session_key, info3.user_sess_key, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
|
||||
}
|
||||
if (state->request.data.auth_crap.flags & WINBIND_PAM_LMKEY) {
|
||||
SMB_ASSERT(sizeof(state->response.data.auth.nt_session_key) <= sizeof(info3.user_sess_key));
|
||||
memcpy(state->response.data.auth.first_8_lm_hash, info3.padding, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
state->response.data.auth.nt_status = NT_STATUS_V(result);
|
||||
fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
|
||||
fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
|
||||
push_utf8_fstring(state->response.data.auth.nt_status_string, nt_errstr(result));
|
||||
push_utf8_fstring(state->response.data.auth.error_string, nt_errstr(result));
|
||||
state->response.data.auth.pam_error = nt_status_to_pam(result);
|
||||
|
||||
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("NTLM CRAP authenticaion for user [%s]\\[%s] returned %s (PAM: %d)\n",
|
||||
state->request.data.auth_crap.domain,
|
||||
state->request.data.auth_crap.user,
|
||||
state->response.data.auth.nt_status_string,
|
||||
state->response.data.auth.pam_error));
|
||||
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
|
||||
("NTLM CRAP authenticaion for user [%s]\\[%s] returned %s (PAM: %d)\n",
|
||||
domain,
|
||||
user,
|
||||
state->response.data.auth.nt_status_string,
|
||||
state->response.data.auth.pam_error));
|
||||
|
||||
if (mem_ctx)
|
||||
talloc_destroy(mem_ctx);
|
||||
|
@ -575,22 +575,23 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint32 *num_domains,
|
||||
char ***names,
|
||||
char ***alt_names,
|
||||
DOM_SID **dom_sids)
|
||||
{
|
||||
CLI_POLICY_HND *hnd;
|
||||
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
|
||||
uint32 enum_ctx = 0;
|
||||
uint32 pref_num_domains = 5;
|
||||
|
||||
DEBUG(3,("rpc: trusted_domains\n"));
|
||||
|
||||
*num_domains = 0;
|
||||
*alt_names = NULL;
|
||||
|
||||
if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
|
||||
goto done;
|
||||
|
||||
result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
|
||||
&hnd->pol, &enum_ctx, &pref_num_domains,
|
||||
&hnd->pol, &enum_ctx,
|
||||
num_domains, names, dom_sids);
|
||||
done:
|
||||
return result;
|
||||
@ -621,6 +622,13 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
/* find alternate names list for the domain - none for rpc */
|
||||
static NTSTATUS alternate_name(struct winbindd_domain *domain)
|
||||
{
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* the rpc backend methods are exposed via this structure */
|
||||
struct winbindd_methods msrpc_methods = {
|
||||
False,
|
||||
@ -633,5 +641,6 @@ struct winbindd_methods msrpc_methods = {
|
||||
lookup_groupmem,
|
||||
sequence_number,
|
||||
trusted_domains,
|
||||
domain_sid
|
||||
domain_sid,
|
||||
alternate_name
|
||||
};
|
||||
|
@ -36,6 +36,9 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state)
|
||||
fstring name;
|
||||
fstring dom_name;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
|
||||
|
||||
DEBUG(3, ("[%5d]: lookupsid %s\n", state->pid,
|
||||
state->request.data.sid));
|
||||
|
||||
@ -79,6 +82,12 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
|
||||
DOM_SID sid;
|
||||
struct winbindd_domain *domain;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.sid[sizeof(state->request.data.name.dom_name)-1]='\0';
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0';
|
||||
|
||||
DEBUG(3, ("[%5d]: lookupname %s%s%s\n", state->pid,
|
||||
state->request.data.name.dom_name,
|
||||
lp_winbind_separator(),
|
||||
@ -112,6 +121,9 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
|
||||
{
|
||||
DOM_SID sid;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
|
||||
|
||||
DEBUG(3, ("[%5d]: sid to uid %s\n", state->pid,
|
||||
state->request.data.sid));
|
||||
|
||||
@ -139,6 +151,9 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
|
||||
{
|
||||
DOM_SID sid;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
|
||||
|
||||
DEBUG(3, ("[%5d]: sid to gid %s\n", state->pid,
|
||||
state->request.data.sid));
|
||||
|
||||
|
@ -103,6 +103,9 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
|
||||
struct winbindd_domain *domain;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.username[sizeof(state->request.data.username)-1]='\0';
|
||||
|
||||
DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid,
|
||||
state->request.data.username));
|
||||
|
||||
|
@ -74,19 +74,17 @@ void free_domain_list(void)
|
||||
}
|
||||
|
||||
/* Add a trusted domain to our list of domains */
|
||||
|
||||
static struct winbindd_domain *add_trusted_domain(char *domain_name,
|
||||
struct winbindd_methods *methods)
|
||||
static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
|
||||
struct winbindd_methods *methods,
|
||||
DOM_SID *sid)
|
||||
{
|
||||
struct winbindd_domain *domain;
|
||||
|
||||
/* We can't call domain_list() as this function is called from
|
||||
init_domain_list() and we'll get stuck in a loop. */
|
||||
|
||||
for (domain = _domain_list; domain; domain = domain->next) {
|
||||
if (strcmp(domain_name, domain->name) == 0) {
|
||||
DEBUG(3, ("domain %s already in domain list\n",
|
||||
domain_name));
|
||||
if (strcmp(domain_name, domain->name) == 0 ||
|
||||
strcmp(domain_name, domain->alt_name) == 0) {
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
@ -101,40 +99,95 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name,
|
||||
|
||||
ZERO_STRUCTP(domain);
|
||||
|
||||
/* prioritise the short name */
|
||||
if (strchr_m(domain_name, '.') && alt_name && *alt_name) {
|
||||
fstrcpy(domain->name, alt_name);
|
||||
fstrcpy(domain->alt_name, domain_name);
|
||||
} else {
|
||||
fstrcpy(domain->name, domain_name);
|
||||
if (alt_name) {
|
||||
fstrcpy(domain->alt_name, alt_name);
|
||||
}
|
||||
}
|
||||
|
||||
domain->methods = methods;
|
||||
domain->sequence_number = DOM_SEQUENCE_NONE;
|
||||
domain->last_seq_check = 0;
|
||||
if (sid) {
|
||||
sid_copy(&domain->sid, sid);
|
||||
}
|
||||
|
||||
/* Link to domain list */
|
||||
|
||||
DLIST_ADD(_domain_list, domain);
|
||||
|
||||
DEBUG(1,("Added domain %s %s %s\n",
|
||||
domain->name, domain->alt_name,
|
||||
sid?sid_string_static(&domain->sid):""));
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
/* Look up global info for the winbind daemon */
|
||||
|
||||
/*
|
||||
rescan our domains looking for new trusted domains
|
||||
*/
|
||||
void rescan_trusted_domains(void)
|
||||
{
|
||||
struct winbindd_domain *domain;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
static time_t last_scan;
|
||||
time_t t = time(NULL);
|
||||
|
||||
/* ony rescan every few minutes */
|
||||
if ((unsigned)(t - last_scan) < WINBINDD_RESCAN_FREQ) {
|
||||
return;
|
||||
}
|
||||
last_scan = time(NULL);
|
||||
|
||||
DEBUG(1, ("scanning trusted domain list\n"));
|
||||
|
||||
if (!(mem_ctx = talloc_init_named("init_domain_list")))
|
||||
return;
|
||||
|
||||
for (domain = _domain_list; domain; domain = domain->next) {
|
||||
NTSTATUS result;
|
||||
char **names;
|
||||
char **alt_names;
|
||||
int num_domains = 0;
|
||||
DOM_SID *dom_sids;
|
||||
int i;
|
||||
|
||||
result = domain->methods->trusted_domains(domain, mem_ctx, &num_domains,
|
||||
&names, &alt_names, &dom_sids);
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Add each domain to the trusted domain list. Each domain inherits
|
||||
the access methods of its parent */
|
||||
for(i = 0; i < num_domains; i++) {
|
||||
DEBUG(10,("Found domain %s\n", names[i]));
|
||||
add_trusted_domain(names[i],
|
||||
alt_names?alt_names[i]:NULL,
|
||||
domain->methods, &dom_sids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
talloc_destroy(mem_ctx);
|
||||
}
|
||||
|
||||
/* Look up global info for the winbind daemon */
|
||||
BOOL init_domain_list(void)
|
||||
{
|
||||
NTSTATUS result;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
extern struct winbindd_methods cache_methods;
|
||||
struct winbindd_domain *domain;
|
||||
DOM_SID *dom_sids;
|
||||
char **names;
|
||||
int num_domains = 0;
|
||||
|
||||
if (!(mem_ctx = talloc_init_named("init_domain_list")))
|
||||
return False;
|
||||
|
||||
/* Free existing list */
|
||||
|
||||
free_domain_list();
|
||||
|
||||
/* Add ourselves as the first entry */
|
||||
|
||||
domain = add_trusted_domain(lp_workgroup(), &cache_methods);
|
||||
domain = add_trusted_domain(lp_workgroup(), NULL, &cache_methods, NULL);
|
||||
|
||||
/* Now we *must* get the domain sid for our primary domain. Go into
|
||||
a holding pattern until that is available */
|
||||
@ -147,29 +200,12 @@ BOOL init_domain_list(void)
|
||||
result = cache_methods.domain_sid(domain, &domain->sid);
|
||||
}
|
||||
|
||||
DEBUG(1,("Added domain %s (%s)\n",
|
||||
domain->name,
|
||||
sid_string_static(&domain->sid)));
|
||||
/* get any alternate name for the primary domain */
|
||||
cache_methods.alternate_name(domain);
|
||||
|
||||
DEBUG(1, ("getting trusted domain list\n"));
|
||||
/* do an initial scan for trusted domains */
|
||||
rescan_trusted_domains();
|
||||
|
||||
result = cache_methods.trusted_domains(domain, mem_ctx, &num_domains,
|
||||
&names, &dom_sids);
|
||||
|
||||
/* Add each domain to the trusted domain list */
|
||||
if (NT_STATUS_IS_OK(result)) {
|
||||
int i;
|
||||
for(i = 0; i < num_domains; i++) {
|
||||
domain = add_trusted_domain(names[i], &cache_methods);
|
||||
if (!domain) continue;
|
||||
sid_copy(&domain->sid, &dom_sids[i]);
|
||||
DEBUG(1,("Added domain %s (%s)\n",
|
||||
domain->name,
|
||||
sid_string_static(&domain->sid)));
|
||||
}
|
||||
}
|
||||
|
||||
talloc_destroy(mem_ctx);
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -184,7 +220,7 @@ struct winbindd_domain *find_domain_from_name(const char *domain_name)
|
||||
|
||||
for (domain = domain_list(); domain != NULL; domain = domain->next) {
|
||||
if (strequal(domain_name, domain->name) ||
|
||||
strequal(domain_name, domain->full_name))
|
||||
(domain->alt_name[0] && strequal(domain_name, domain->alt_name)))
|
||||
return domain;
|
||||
}
|
||||
|
||||
|
@ -122,6 +122,9 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
|
||||
int i, count, maxlen, size;
|
||||
struct node_status *status;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
|
||||
|
||||
DEBUG(3, ("[%5d]: wins_byip %s\n", state->pid,
|
||||
state->request.data.winsreq));
|
||||
|
||||
@ -166,6 +169,9 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
|
||||
fstring response;
|
||||
char * addr;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
|
||||
|
||||
DEBUG(3, ("[%5d]: wins_byname %s\n", state->pid,
|
||||
state->request.data.winsreq));
|
||||
|
||||
|
@ -87,6 +87,7 @@ static BOOL defaults_saved = False;
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *smb_ports;
|
||||
char *dos_charset;
|
||||
char *unix_charset;
|
||||
char *display_charset;
|
||||
@ -165,6 +166,7 @@ typedef struct
|
||||
char *szGuestaccount;
|
||||
char *szManglingMethod;
|
||||
int max_log_size;
|
||||
char *szLogLevel;
|
||||
int mangled_stack;
|
||||
int max_xmit;
|
||||
int max_mux;
|
||||
@ -256,7 +258,9 @@ typedef struct
|
||||
BOOL bHostnameLookups;
|
||||
BOOL bUseSpnego;
|
||||
BOOL bUnixExtensions;
|
||||
BOOL bDisableNetbios;
|
||||
int restrict_anonymous;
|
||||
int name_cache_timeout;
|
||||
}
|
||||
global;
|
||||
|
||||
@ -313,6 +317,7 @@ typedef struct
|
||||
char *fstype;
|
||||
char *szVfsObjectFile;
|
||||
char *szVfsOptions;
|
||||
char *szVfsPath;
|
||||
int iMinPrintSpace;
|
||||
int iMaxPrintJobs;
|
||||
int iWriteCacheSize;
|
||||
@ -339,6 +344,7 @@ typedef struct
|
||||
BOOL bCaseMangle;
|
||||
BOOL bHideDotFiles;
|
||||
BOOL bHideUnReadable;
|
||||
BOOL bHideUnWriteableFiles;
|
||||
BOOL bBrowseable;
|
||||
BOOL bAvailable;
|
||||
BOOL bRead_only;
|
||||
@ -431,6 +437,7 @@ static service sDefault = {
|
||||
NULL, /* fstype */
|
||||
NULL, /* vfs object */
|
||||
NULL, /* vfs options */
|
||||
NULL, /* vfs path */
|
||||
0, /* iMinPrintSpace */
|
||||
1000, /* iMaxPrintJobs */
|
||||
0, /* iWriteCacheSize */
|
||||
@ -457,6 +464,7 @@ static service sDefault = {
|
||||
False, /* case mangle */
|
||||
True, /* bHideDotFiles */
|
||||
False, /* bHideUnReadable */
|
||||
False, /* bHideUnWriteableFiles */
|
||||
True, /* bBrowseable */
|
||||
True, /* bAvailable */
|
||||
True, /* bRead_only */
|
||||
@ -545,7 +553,9 @@ static struct enum_list enum_security[] = {
|
||||
{SEC_USER, "USER"},
|
||||
{SEC_SERVER, "SERVER"},
|
||||
{SEC_DOMAIN, "DOMAIN"},
|
||||
#ifdef HAVE_ADS
|
||||
{SEC_ADS, "ADS"},
|
||||
#endif
|
||||
{-1, NULL}
|
||||
};
|
||||
|
||||
@ -759,8 +769,8 @@ static struct parm_struct parm_table[] = {
|
||||
{"Logging Options", P_SEP, P_SEPARATOR},
|
||||
|
||||
{"admin log", P_BOOL, P_GLOBAL, &Globals.bAdminLog, NULL, NULL, 0},
|
||||
{"log level", P_STRING, P_GLOBAL, NULL, handle_debug_list, NULL, 0},
|
||||
{"debuglevel", P_STRING, P_GLOBAL, NULL, handle_debug_list, NULL, 0},
|
||||
{"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, 0},
|
||||
{"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, 0},
|
||||
{"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
|
||||
{"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
|
||||
{"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
|
||||
@ -774,6 +784,7 @@ static struct parm_struct parm_table[] = {
|
||||
|
||||
{"Protocol Options", P_SEP, P_SEPARATOR},
|
||||
|
||||
{"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, 0},
|
||||
{"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
|
||||
{"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, 0},
|
||||
{"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
|
||||
@ -782,6 +793,7 @@ static struct parm_struct parm_table[] = {
|
||||
{"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
|
||||
{"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
|
||||
{"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
|
||||
{"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, 0},
|
||||
|
||||
{"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0},
|
||||
{"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE },
|
||||
@ -827,6 +839,8 @@ static struct parm_struct parm_table[] = {
|
||||
{"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, 0},
|
||||
{"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
|
||||
|
||||
{"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, 0},
|
||||
|
||||
{"Printing Options", P_SEP, P_SEPARATOR},
|
||||
|
||||
{"total print jobs", P_INTEGER, P_GLOBAL, &Globals.iTotalPrintJobs, NULL, NULL, FLAG_PRINT},
|
||||
@ -875,6 +889,7 @@ static struct parm_struct parm_table[] = {
|
||||
{"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
|
||||
{"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
|
||||
{"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
|
||||
{"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
|
||||
{"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
|
||||
{"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
|
||||
{"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
|
||||
@ -1021,6 +1036,7 @@ static struct parm_struct parm_table[] = {
|
||||
|
||||
{"vfs object", P_STRING, P_LOCAL, &sDefault.szVfsObjectFile, handle_vfs_object, NULL, FLAG_SHARE},
|
||||
{"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE},
|
||||
{"vfs path", P_STRING, P_LOCAL, &sDefault.szVfsPath, NULL, NULL, FLAG_SHARE},
|
||||
|
||||
|
||||
{"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
|
||||
@ -1057,26 +1073,26 @@ static void init_printer_values(void)
|
||||
case PRINT_AIX:
|
||||
case PRINT_LPRNT:
|
||||
case PRINT_LPROS2:
|
||||
string_set(&sDefault.szLpqcommand, "lpq -P%p");
|
||||
string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
|
||||
string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
|
||||
string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
|
||||
string_set(&sDefault.szPrintcommand,
|
||||
"lpr -r -P%p %s");
|
||||
"lpr -r -P'%p' %s");
|
||||
break;
|
||||
|
||||
case PRINT_LPRNG:
|
||||
case PRINT_PLP:
|
||||
string_set(&sDefault.szLpqcommand, "lpq -P%p");
|
||||
string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
|
||||
string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
|
||||
string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
|
||||
string_set(&sDefault.szPrintcommand,
|
||||
"lpr -r -P%p %s");
|
||||
"lpr -r -P'%p' %s");
|
||||
string_set(&sDefault.szQueuepausecommand,
|
||||
"lpc stop %p");
|
||||
"lpc stop '%p'");
|
||||
string_set(&sDefault.szQueueresumecommand,
|
||||
"lpc start %p");
|
||||
"lpc start '%p'");
|
||||
string_set(&sDefault.szLppausecommand,
|
||||
"lpc hold %p %j");
|
||||
"lpc hold '%p' %j");
|
||||
string_set(&sDefault.szLpresumecommand,
|
||||
"lpc release %p %j");
|
||||
"lpc release '%p' %j");
|
||||
break;
|
||||
|
||||
case PRINT_CUPS:
|
||||
@ -1092,19 +1108,19 @@ static void init_printer_values(void)
|
||||
string_set(&Globals.szPrintcapname, "cups");
|
||||
#else
|
||||
string_set(&sDefault.szLpqcommand,
|
||||
"/usr/bin/lpstat -o %p");
|
||||
"/usr/bin/lpstat -o '%p'");
|
||||
string_set(&sDefault.szLprmcommand,
|
||||
"/usr/bin/cancel %p-%j");
|
||||
"/usr/bin/cancel '%p-%j'");
|
||||
string_set(&sDefault.szPrintcommand,
|
||||
"/usr/bin/lp -d %p %s; rm %s");
|
||||
"/usr/bin/lp -d '%p' %s; rm %s");
|
||||
string_set(&sDefault.szLppausecommand,
|
||||
"lp -i %p-%j -H hold");
|
||||
"lp -i '%p-%j' -H hold");
|
||||
string_set(&sDefault.szLpresumecommand,
|
||||
"lp -i %p-%j -H resume");
|
||||
"lp -i '%p-%j' -H resume");
|
||||
string_set(&sDefault.szQueuepausecommand,
|
||||
"/usr/bin/disable %p");
|
||||
"/usr/bin/disable '%p'");
|
||||
string_set(&sDefault.szQueueresumecommand,
|
||||
"/usr/bin/enable %p");
|
||||
"/usr/bin/enable '%p'");
|
||||
string_set(&Globals.szPrintcapname, "lpstat");
|
||||
#endif /* HAVE_CUPS */
|
||||
break;
|
||||
@ -1191,7 +1207,7 @@ static void init_globals(void)
|
||||
|
||||
string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
|
||||
string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
|
||||
Globals.szPassdbBackend = str_list_make("smbpasswd unixsam");
|
||||
Globals.szPassdbBackend = str_list_make("smbpasswd unixsam", NULL);
|
||||
|
||||
/* use the new 'hash2' method by default */
|
||||
string_set(&Globals.szManglingMethod, "hash2");
|
||||
@ -1201,6 +1217,9 @@ static void init_globals(void)
|
||||
/* using UTF8 by default allows us to support all chars */
|
||||
string_set(&Globals.unix_charset, "UTF8");
|
||||
|
||||
/* Use codepage 850 as a default for the dos character set */
|
||||
string_set(&Globals.dos_charset, "CP850");
|
||||
|
||||
/*
|
||||
* Allow the default PASSWD_CHAT to be overridden in local.h.
|
||||
*/
|
||||
@ -1262,6 +1281,7 @@ static void init_globals(void)
|
||||
Globals.bSyslogOnly = False;
|
||||
Globals.bAdminLog = False;
|
||||
Globals.bTimestampLogs = True;
|
||||
string_set(&Globals.szLogLevel, "0");
|
||||
Globals.bDebugHiresTimestamp = False;
|
||||
Globals.bDebugPid = False;
|
||||
Globals.bDebugUid = False;
|
||||
@ -1358,8 +1378,11 @@ static void init_globals(void)
|
||||
Globals.bWinbindEnumGroups = True;
|
||||
Globals.bWinbindUseDefaultDomain = False;
|
||||
|
||||
Globals.name_cache_timeout = 660; /* In seconds */
|
||||
|
||||
Globals.bUseSpnego = True;
|
||||
|
||||
string_set(&Globals.smb_ports, SMB_PORTS);
|
||||
}
|
||||
|
||||
static TALLOC_CTX *lp_talloc;
|
||||
@ -1407,7 +1430,10 @@ static char *lp_string(const char *s)
|
||||
else
|
||||
StrnCpy(ret, s, len);
|
||||
|
||||
trim_string(ret, "\"", "\"");
|
||||
if (trim_string(ret, "\"", "\"")) {
|
||||
if (strchr(ret,'"') != NULL)
|
||||
StrnCpy(ret, s, len);
|
||||
}
|
||||
|
||||
standard_sub_basic(current_user_info.smb_name,ret,len+100);
|
||||
return (ret);
|
||||
@ -1445,6 +1471,7 @@ static char *lp_string(const char *s)
|
||||
#define FN_LOCAL_INTEGER(fn_name,val) \
|
||||
int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
|
||||
|
||||
FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
|
||||
FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
|
||||
FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
|
||||
FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
|
||||
@ -1498,7 +1525,7 @@ FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
|
||||
FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
|
||||
FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
|
||||
|
||||
FN_GLOBAL_STRING(lp_guestaccount, &Globals.szGuestaccount)
|
||||
FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
|
||||
FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
|
||||
FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
|
||||
FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
|
||||
@ -1527,6 +1554,7 @@ FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
|
||||
FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
|
||||
FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
|
||||
|
||||
FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
|
||||
FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
|
||||
FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
|
||||
FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
|
||||
@ -1642,6 +1670,7 @@ FN_LOCAL_LIST(lp_printer_admin, printer_admin)
|
||||
FN_LOCAL_STRING(lp_fstype, fstype)
|
||||
FN_LOCAL_STRING(lp_vfsobj, szVfsObjectFile)
|
||||
FN_LOCAL_STRING(lp_vfs_options, szVfsOptions)
|
||||
FN_LOCAL_STRING(lp_vfs_path, szVfsPath)
|
||||
static FN_LOCAL_STRING(lp_volume, volume)
|
||||
FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
|
||||
FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
|
||||
@ -1658,6 +1687,7 @@ FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
|
||||
FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
|
||||
FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
|
||||
FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
|
||||
FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
|
||||
FN_LOCAL_BOOL(lp_browseable, bBrowseable)
|
||||
FN_LOCAL_BOOL(lp_readonly, bRead_only)
|
||||
FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
|
||||
@ -1715,6 +1745,7 @@ FN_LOCAL_CHAR(lp_magicchar, magic_char)
|
||||
FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
|
||||
FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
|
||||
FN_GLOBAL_BOOL(lp_algorithmic_rid_base, &Globals.bAlgorithmicRidBase)
|
||||
FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
|
||||
|
||||
typedef struct _param_opt_struct param_opt_struct;
|
||||
struct _param_opt_struct {
|
||||
@ -1904,8 +1935,8 @@ BOOL lp_add_home(const char *pszHomename, int iDefaultService,
|
||||
if (i < 0)
|
||||
return (False);
|
||||
|
||||
if (!(*(ServicePtrs[i]->szPath))
|
||||
|| strequal(ServicePtrs[i]->szPath, lp_pathname(-1))) {
|
||||
if (!(*(ServicePtrs[iDefaultService]->szPath))
|
||||
|| strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
|
||||
pstrcpy(newHomedir, pszHomedir);
|
||||
} else {
|
||||
pstrcpy(newHomedir, lp_pathname(iDefaultService));
|
||||
@ -1925,7 +1956,7 @@ BOOL lp_add_home(const char *pszHomename, int iDefaultService,
|
||||
ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
|
||||
|
||||
DEBUG(3,
|
||||
("adding home's share [%s] for user %s at %s\n", pszHomename,
|
||||
("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
|
||||
user, newHomedir));
|
||||
|
||||
return (True);
|
||||
@ -1971,14 +2002,12 @@ static BOOL lp_add_ipc(char *ipc_name, BOOL guest_ok)
|
||||
return (True);
|
||||
}
|
||||
|
||||
BOOL (*register_printer_fn)(const char *);
|
||||
|
||||
/***************************************************************************
|
||||
add a new printer service, with defaults coming from service iFrom.
|
||||
***************************************************************************/
|
||||
BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
|
||||
BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
|
||||
{
|
||||
char *comment = "From Printcap";
|
||||
const char *comment = "From Printcap";
|
||||
int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
|
||||
|
||||
if (i < 0)
|
||||
@ -2005,8 +2034,6 @@ BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
|
||||
DEBUG(3, ("adding printer service %s\n", pszPrintername));
|
||||
|
||||
update_server_announce_as_printserver();
|
||||
if (register_printer_fn && (!(*register_printer_fn)(pszPrintername)))
|
||||
return False;
|
||||
|
||||
return (True);
|
||||
}
|
||||
@ -2623,6 +2650,7 @@ static BOOL handle_debug_list( char *pszParmValueIn, char **ptr )
|
||||
pstring pszParmValue;
|
||||
|
||||
pstrcpy(pszParmValue, pszParmValueIn);
|
||||
string_set(ptr, pszParmValueIn);
|
||||
return debug_parse_levels( pszParmValue );
|
||||
}
|
||||
|
||||
@ -2844,7 +2872,7 @@ BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
|
||||
break;
|
||||
|
||||
case P_LIST:
|
||||
*(char ***)parm_ptr = str_list_make(pszParmValue);
|
||||
*(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
|
||||
break;
|
||||
|
||||
case P_STRING:
|
||||
@ -3485,8 +3513,8 @@ static void set_server_role(void)
|
||||
case SEC_DOMAIN:
|
||||
case SEC_ADS:
|
||||
if (lp_domain_logons()) {
|
||||
server_role = ROLE_DOMAIN_BDC;
|
||||
DEBUG(10,("set_server_role:ROLE_DOMAIN_BDC\n"));
|
||||
server_role = ROLE_DOMAIN_PDC;
|
||||
DEBUG(10,("set_server_role:ROLE_DOMAIN_PDC\n"));
|
||||
break;
|
||||
}
|
||||
server_role = ROLE_DOMAIN_MEMBER;
|
||||
|
@ -157,6 +157,12 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
|
||||
{
|
||||
GROUP_MAP map;
|
||||
|
||||
const char *guest_account = lp_guestaccount();
|
||||
if (!(guest_account && *guest_account)) {
|
||||
DEBUG(1, ("NULL guest account!?!?\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (!pwd) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
@ -183,23 +189,35 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
|
||||
-- abartlet 11-May-02
|
||||
*/
|
||||
|
||||
if (!pdb_set_user_sid_from_rid(sam_account,
|
||||
fallback_pdb_uid_to_user_rid(pwd->pw_uid))) {
|
||||
DEBUG(0,("Can't set User SID from RID!\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* call the mapping code here */
|
||||
if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
|
||||
if (!pdb_set_group_sid(sam_account,&map.sid)){
|
||||
DEBUG(0,("Can't set Group SID!\n"));
|
||||
/* Ensure this *must* be set right */
|
||||
if (strcmp(pwd->pw_name, guest_account) == 0) {
|
||||
if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST)) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS)) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (!pdb_set_user_sid_from_rid(sam_account,
|
||||
fallback_pdb_uid_to_user_rid(pwd->pw_uid))) {
|
||||
DEBUG(0,("Can't set User SID from RID!\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) {
|
||||
DEBUG(0,("Can't set Group SID\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* call the mapping code here */
|
||||
if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
|
||||
if (!pdb_set_group_sid(sam_account,&map.sid)){
|
||||
DEBUG(0,("Can't set Group SID!\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) {
|
||||
DEBUG(0,("Can't set Group SID\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -528,6 +546,9 @@ BOOL pdb_rid_is_user(uint32 rid)
|
||||
* such that it can be identified as either a user, group etc
|
||||
* type. there are 5 such categories, and they are documented.
|
||||
*/
|
||||
/* However, they are not in the RID, just somthing you can query
|
||||
seperatly. Sorry luke :-) */
|
||||
|
||||
if(pdb_rid_is_well_known(rid)) {
|
||||
/*
|
||||
* The only well known user RIDs are DOMAIN_USER_RID_ADMIN
|
||||
@ -571,14 +592,6 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
|
||||
fstrcpy(name, "Administrator");
|
||||
}
|
||||
return True;
|
||||
|
||||
} else if (rid == DOMAIN_USER_RID_GUEST) {
|
||||
char *p = lp_guestaccount();
|
||||
*psid_name_use = SID_NAME_USER;
|
||||
if(!next_token(&p, name, NULL, sizeof(fstring)))
|
||||
fstrcpy(name, "Guest");
|
||||
return True;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -594,6 +607,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
|
||||
}
|
||||
|
||||
/* This now does the 'generic' mapping in pdb_unix */
|
||||
/* 'guest' is also handled there */
|
||||
if (pdb_getsampwsid(sam_account, sid)) {
|
||||
fstrcpy(name, pdb_get_username(sam_account));
|
||||
*psid_name_use = SID_NAME_USER;
|
||||
@ -716,15 +730,9 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
|
||||
|
||||
/* check if it's a mapped group */
|
||||
if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) {
|
||||
if (map.gid!=-1) {
|
||||
/* yes it's a mapped group to a valid unix group */
|
||||
sid_copy(&local_sid, &map.sid);
|
||||
*psid_name_use = map.sid_name_use;
|
||||
}
|
||||
else {
|
||||
/* it's a correct name but not mapped so it points to nothing*/
|
||||
return False;
|
||||
}
|
||||
/* yes it's a mapped group */
|
||||
sid_copy(&local_sid, &map.sid);
|
||||
*psid_name_use = map.sid_name_use;
|
||||
} else {
|
||||
/* it's not a mapped group */
|
||||
grp = getgrnam(user);
|
||||
@ -777,6 +785,8 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
|
||||
|
||||
if (pdb_getsampwnam(sam_user, pass->pw_name)) {
|
||||
sid_copy(psid, pdb_get_user_sid(sam_user));
|
||||
} else if (strcmp(pass->pw_name, lp_guestaccount()) == 0) {
|
||||
sid_append_rid(psid, DOMAIN_USER_RID_GUEST);
|
||||
} else {
|
||||
sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid));
|
||||
}
|
||||
@ -802,25 +812,13 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
|
||||
Convert a SID to uid - locally.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
||||
BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
|
||||
{
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
fstring str;
|
||||
SAM_ACCOUNT *sam_user = NULL;
|
||||
|
||||
*name_type = SID_NAME_UNKNOWN;
|
||||
|
||||
sid_copy(&dom_sid, psid);
|
||||
sid_split_rid(&dom_sid, &rid);
|
||||
|
||||
/*
|
||||
* We can only convert to a uid if this is our local
|
||||
* Domain SID (ie. we are the controling authority).
|
||||
*/
|
||||
if (!sid_equal(get_global_sam_sid(), &dom_sid))
|
||||
return False;
|
||||
|
||||
if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user)))
|
||||
return False;
|
||||
|
||||
@ -832,12 +830,37 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
||||
}
|
||||
DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid),
|
||||
(unsigned int)*puid, pdb_get_username(sam_user)));
|
||||
} else {
|
||||
DEBUG(5,("local_sid_to_uid: SID %s not mapped becouse RID was not found in passdb.\n", sid_to_string( str, psid)));
|
||||
pdb_free_sam(&sam_user);
|
||||
return False;
|
||||
} else {
|
||||
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
GROUP_MAP map;
|
||||
|
||||
pdb_free_sam(&sam_user);
|
||||
|
||||
if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) {
|
||||
DEBUG(3, ("local_sid_to_uid: SID '%s' is a group, not a user... \n", sid_to_string(str, psid)));
|
||||
/* It's a group, not a user... */
|
||||
return False;
|
||||
}
|
||||
|
||||
sid_copy(&dom_sid, psid);
|
||||
if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
|
||||
DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!pdb_rid_is_user(rid)) {
|
||||
DEBUG(3, ("local_sid_to_uid: sid '%s' cannot be mapped to a uid algorithmicly becouse it is a group\n", sid_to_string(str, psid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
*puid = fallback_pdb_user_rid_to_uid(rid);
|
||||
|
||||
DEBUG(5,("local_sid_to_uid: SID %s algorithmicly mapped to %ld mapped becouse SID was not found in passdb.\n",
|
||||
sid_to_string(str, psid), (signed long int)(*puid)));
|
||||
}
|
||||
pdb_free_sam(&sam_user);
|
||||
|
||||
*name_type = SID_NAME_USER;
|
||||
|
||||
@ -868,18 +891,13 @@ DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
|
||||
Convert a SID to gid - locally.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
||||
BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
|
||||
{
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
fstring str;
|
||||
GROUP_MAP map;
|
||||
|
||||
*name_type = SID_NAME_UNKNOWN;
|
||||
|
||||
sid_copy(&dom_sid, psid);
|
||||
sid_split_rid(&dom_sid, &rid);
|
||||
|
||||
/*
|
||||
* We can only convert to a gid if this is our local
|
||||
* Domain SID (ie. we are the controling authority).
|
||||
@ -887,35 +905,45 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
||||
* Or in the Builtin SID too. JFM, 11/30/2001
|
||||
*/
|
||||
|
||||
if (!sid_equal(get_global_sam_sid(), &dom_sid))
|
||||
return False;
|
||||
|
||||
if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) {
|
||||
|
||||
/* the SID is in the mapping table but not mapped */
|
||||
if (map.gid==-1)
|
||||
return False;
|
||||
|
||||
if (!sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)){
|
||||
DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n",
|
||||
sid_string_static(&map.sid)));
|
||||
return False;
|
||||
}
|
||||
*pgid = map.gid;
|
||||
*name_type = map.sid_name_use;
|
||||
DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", sid_to_string( str, psid),
|
||||
DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n",
|
||||
sid_to_string( str, psid),
|
||||
map.nt_name, (unsigned int)*pgid));
|
||||
|
||||
} else {
|
||||
uint32 rid;
|
||||
SAM_ACCOUNT *sam_user = NULL;
|
||||
if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user)))
|
||||
return False;
|
||||
|
||||
if (pdb_getsampwsid(sam_user, psid)) {
|
||||
return False;
|
||||
pdb_free_sam(&sam_user);
|
||||
}
|
||||
|
||||
pdb_free_sam(&sam_user);
|
||||
|
||||
if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
|
||||
DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (pdb_rid_is_user(rid))
|
||||
return False;
|
||||
|
||||
|
||||
*pgid = pdb_group_rid_to_gid(rid);
|
||||
*name_type = SID_NAME_ALIAS;
|
||||
DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u).\n", sid_to_string( str, psid),
|
||||
(unsigned int)*pgid));
|
||||
}
|
||||
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
const char* pdb_get_dirdrive (const SAM_ACCOUNT *sampass)
|
||||
const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass)
|
||||
{
|
||||
if (sampass)
|
||||
return (sampass->private.dir_drive);
|
||||
@ -1028,15 +1028,14 @@ BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
|
||||
if (!pdb_set_pass_last_set_time (sampass, time(NULL)))
|
||||
return False;
|
||||
|
||||
account_policy_get(AP_MAX_PASSWORD_AGE, &expire);
|
||||
|
||||
if (expire==(uint32)-1) {
|
||||
if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
|
||||
|| (expire==(uint32)-1)) {
|
||||
if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), False))
|
||||
return False;
|
||||
} else {
|
||||
if (!pdb_set_pass_must_change_time (sampass,
|
||||
pdb_get_pass_last_set_time(sampass)
|
||||
+ expire, True))
|
||||
pdb_get_pass_last_set_time(sampass)
|
||||
+ expire, True))
|
||||
return False;
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ static BOOL context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_ac
|
||||
return False;
|
||||
}
|
||||
|
||||
static BOOL context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, DOM_SID *sid)
|
||||
static BOOL context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
|
||||
{
|
||||
struct pdb_methods *curmethods;
|
||||
if ((!context)) {
|
||||
@ -353,7 +353,7 @@ NTSTATUS make_pdb_context_list(struct pdb_context **context, char **selected)
|
||||
NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
char **newsel = str_list_make(selected);
|
||||
char **newsel = str_list_make(selected, NULL);
|
||||
ret = make_pdb_context_list(context, newsel);
|
||||
str_list_free(&newsel);
|
||||
return ret;
|
||||
@ -434,7 +434,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
|
||||
return pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username);
|
||||
}
|
||||
|
||||
BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, DOM_SID *sid)
|
||||
BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
|
||||
{
|
||||
struct pdb_context *pdb_context = pdb_get_static_context(False);
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
LDAP protocol helper functions for SAMBA
|
||||
Copyright (C) Gerald Carter 2001
|
||||
Copyright (C) Shahms King 2001
|
||||
Copyright (C) Jean François Micouleau 1998
|
||||
Copyright (C) Andrew Bartlett 2002
|
||||
|
||||
Copyright (C) Jean François Micouleau 1998
|
||||
Copyright (C) Gerald Carter 2001
|
||||
Copyright (C) Shahms King 2001
|
||||
Copyright (C) Andrew Bartlett 2002
|
||||
Copyright (C) Stefan (metze) Metzmacher 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
|
||||
@ -70,8 +71,14 @@ struct ldapsam_privates {
|
||||
|
||||
uint32 low_nua_rid;
|
||||
uint32 high_nua_rid;
|
||||
|
||||
char *bind_dn;
|
||||
char *bind_secret;
|
||||
};
|
||||
|
||||
|
||||
static struct ldapsam_privates *static_ldap_state;
|
||||
|
||||
static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
|
||||
|
||||
/*******************************************************************
|
||||
@ -153,11 +160,13 @@ static const char *attr[] = {"uid", "pwdLastSet", "logonTime",
|
||||
static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
|
||||
{
|
||||
|
||||
int version;
|
||||
|
||||
if (geteuid() != 0) {
|
||||
DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root..\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
|
||||
DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
|
||||
|
||||
@ -165,6 +174,16 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
|
||||
DEBUG(0, ("ldap_initialize: %s\n", strerror(errno)));
|
||||
return (False);
|
||||
}
|
||||
|
||||
if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
|
||||
{
|
||||
if (version != LDAP_VERSION3)
|
||||
{
|
||||
version = LDAP_VERSION3;
|
||||
ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Parse the string manually */
|
||||
@ -173,7 +192,6 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
|
||||
int rc;
|
||||
int tls = LDAP_OPT_X_TLS_HARD;
|
||||
int port = 0;
|
||||
int version;
|
||||
fstring protocol;
|
||||
fstring host;
|
||||
const char *p = ldap_state->uri;
|
||||
@ -251,6 +269,67 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
a rebind function for authenticated referrals
|
||||
This version takes a void* that we can shove useful stuff in :-)
|
||||
******************************************************************/
|
||||
|
||||
static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
|
||||
int *methodp, int freeit, void *arg)
|
||||
{
|
||||
struct ldapsam_privates *ldap_state = arg;
|
||||
|
||||
/** @TODO Should we be doing something to check what servers we rebind to?
|
||||
Could we get a referral to a machine that we don't want to give our
|
||||
username and password to? */
|
||||
|
||||
if (freeit) {
|
||||
SAFE_FREE(*whop);
|
||||
memset(*credp, '\0', strlen(*credp));
|
||||
SAFE_FREE(*credp);
|
||||
} else {
|
||||
DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
|
||||
ldap_state->bind_dn));
|
||||
|
||||
*whop = strdup(ldap_state->bind_dn);
|
||||
if (!*whop) {
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
*credp = strdup(ldap_state->bind_secret);
|
||||
if (!*credp) {
|
||||
SAFE_FREE(*whop);
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
*methodp = LDAP_AUTH_SIMPLE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
a rebind function for authenticated referrals
|
||||
This version takes a void* that we can shove useful stuff in :-)
|
||||
and actually does the connection.
|
||||
******************************************************************/
|
||||
|
||||
static int rebindproc_connect_with_state (LDAP *ldap_struct,
|
||||
LDAP_CONST char *url,
|
||||
ber_tag_t request,
|
||||
ber_int_t msgid, void *arg)
|
||||
{
|
||||
struct ldapsam_privates *ldap_state = arg;
|
||||
int rc;
|
||||
DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
|
||||
ldap_state->bind_dn));
|
||||
|
||||
/** @TODO Should we be doing something to check what servers we rebind to?
|
||||
Could we get a referral to a machine that we don't want to give our
|
||||
username and password to? */
|
||||
|
||||
rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Add a rebind function for authenticated referrals
|
||||
******************************************************************/
|
||||
@ -258,36 +337,24 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
|
||||
static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
|
||||
int *method, int freeit )
|
||||
{
|
||||
int rc;
|
||||
char *ldap_dn;
|
||||
char *ldap_secret;
|
||||
return rebindproc_with_state(ldap_struct, whop, credp,
|
||||
method, freeit, static_ldap_state);
|
||||
|
||||
/** @TODO Should we be doing something to check what servers we rebind to?
|
||||
Could we get a referral to a machine that we don't want to give our
|
||||
username and password to? */
|
||||
|
||||
if (freeit != 0)
|
||||
{
|
||||
|
||||
if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
|
||||
{
|
||||
DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
|
||||
return LDAP_OPERATIONS_ERROR; /* No idea what to return */
|
||||
}
|
||||
|
||||
DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
|
||||
ldap_dn));
|
||||
|
||||
rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
|
||||
|
||||
SAFE_FREE(ldap_dn);
|
||||
SAFE_FREE(ldap_secret);
|
||||
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
a rebind function for authenticated referrals
|
||||
this also does the connection, but no void*.
|
||||
******************************************************************/
|
||||
|
||||
static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
|
||||
ber_int_t msgid)
|
||||
{
|
||||
return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
|
||||
static_ldap_state);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
connect to the ldap server under system privilege.
|
||||
******************************************************************/
|
||||
@ -297,6 +364,10 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l
|
||||
char *ldap_dn;
|
||||
char *ldap_secret;
|
||||
|
||||
/* The rebind proc needs this *HACK*. We are not multithreaded, so
|
||||
this will work, but it's not nice. */
|
||||
static_ldap_state = ldap_state;
|
||||
|
||||
/* get the password */
|
||||
if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
|
||||
{
|
||||
@ -304,19 +375,32 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l
|
||||
return False;
|
||||
}
|
||||
|
||||
ldap_state->bind_dn = ldap_dn;
|
||||
ldap_state->bind_secret = ldap_secret;
|
||||
|
||||
/* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
|
||||
(OpenLDAP) doesnt' seem to support it */
|
||||
|
||||
DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
|
||||
ldap_dn));
|
||||
|
||||
ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc));
|
||||
|
||||
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
|
||||
# if LDAP_SET_REBIND_PROC_ARGS == 2
|
||||
ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
|
||||
# endif
|
||||
# if LDAP_SET_REBIND_PROC_ARGS == 3
|
||||
ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
|
||||
# endif
|
||||
#else
|
||||
# if LDAP_SET_REBIND_PROC_ARGS == 2
|
||||
ldap_set_rebind_proc(ldap_struct, &rebindproc);
|
||||
# endif
|
||||
# if LDAP_SET_REBIND_PROC_ARGS == 3
|
||||
ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
|
||||
# endif
|
||||
#endif
|
||||
rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
|
||||
|
||||
SAFE_FREE(ldap_dn);
|
||||
SAFE_FREE(ldap_secret);
|
||||
|
||||
if (rc != LDAP_SUCCESS)
|
||||
{
|
||||
DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
|
||||
@ -756,18 +840,20 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
|
||||
/* leave as default */
|
||||
} else {
|
||||
pdb_gethexpwd(temp, smblmpwd);
|
||||
memset((char *)temp, '\0', sizeof(temp));
|
||||
memset((char *)temp, '\0', strlen(temp)+1);
|
||||
if (!pdb_set_lanman_passwd(sampass, smblmpwd))
|
||||
return False;
|
||||
ZERO_STRUCT(smblmpwd);
|
||||
}
|
||||
|
||||
if (!get_single_attribute (ldap_struct, entry, "ntPassword", temp)) {
|
||||
/* leave as default */
|
||||
} else {
|
||||
pdb_gethexpwd(temp, smbntpwd);
|
||||
memset((char *)temp, '\0', sizeof(temp));
|
||||
memset((char *)temp, '\0', strlen(temp)+1);
|
||||
if (!pdb_set_nt_passwd(sampass, smbntpwd))
|
||||
return False;
|
||||
ZERO_STRUCT(smbntpwd);
|
||||
}
|
||||
|
||||
if (!get_single_attribute (ldap_struct, entry, "acctFlags", temp)) {
|
||||
@ -880,7 +966,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
|
||||
make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass));
|
||||
|
||||
if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE))
|
||||
make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dirdrive(sampass));
|
||||
make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass));
|
||||
|
||||
if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT))
|
||||
make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass));
|
||||
@ -1153,6 +1239,10 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us
|
||||
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
|
||||
BOOL ret = False;
|
||||
|
||||
/* The rebind proc needs this *HACK*. We are not multithreaded, so
|
||||
this will work, but it's not nice. */
|
||||
static_ldap_state = ldap_state;
|
||||
|
||||
while (!ret) {
|
||||
if (!ldap_state->entry)
|
||||
return False;
|
||||
@ -1203,7 +1293,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us
|
||||
if (entry)
|
||||
{
|
||||
if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) {
|
||||
DEBUG(0,("ldapsam_getsampwnam: init_sam_from_ldap failed!\n"));
|
||||
DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
|
||||
ldap_msgfree(result);
|
||||
ldap_unbind(ldap_struct);
|
||||
return False;
|
||||
@ -1247,7 +1337,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
|
||||
|
||||
if (ldap_count_entries(ldap_struct, result) < 1)
|
||||
{
|
||||
DEBUG(0,
|
||||
DEBUG(4,
|
||||
("We don't find this rid [%i] count=%d\n", rid,
|
||||
ldap_count_entries(ldap_struct, result)));
|
||||
ldap_unbind(ldap_struct);
|
||||
@ -1258,7 +1348,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
|
||||
if (entry)
|
||||
{
|
||||
if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) {
|
||||
DEBUG(0,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
|
||||
DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
|
||||
ldap_msgfree(result);
|
||||
ldap_unbind(ldap_struct);
|
||||
return False;
|
||||
@ -1275,7 +1365,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
|
||||
static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
|
||||
{
|
||||
uint32 rid;
|
||||
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
|
||||
@ -1530,6 +1620,13 @@ static void free_private_data(void **vp)
|
||||
ldap_unbind((*ldap_state)->ldap_struct);
|
||||
}
|
||||
|
||||
if ((*ldap_state)->bind_secret) {
|
||||
memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
|
||||
}
|
||||
|
||||
SAFE_FREE((*ldap_state)->bind_dn);
|
||||
SAFE_FREE((*ldap_state)->bind_secret);
|
||||
|
||||
*ldap_state = NULL;
|
||||
|
||||
/* No need to free any further, as it is talloc()ed */
|
||||
|
@ -735,17 +735,17 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
|
||||
|
||||
/* dir_drive */
|
||||
/* must support set, unset and change */
|
||||
if( (pdb_get_dirdrive(sampass) &&
|
||||
if( (pdb_get_dir_drive(sampass) &&
|
||||
!ENTRY_VAL(old, NPF_DIR_DRIVE)) ||
|
||||
(ENTRY_VAL(old, NPF_DIR_DRIVE) &&
|
||||
!pdb_get_dirdrive(sampass)) ||
|
||||
!pdb_get_dir_drive(sampass)) ||
|
||||
(ENTRY_VAL(old, NPF_DIR_DRIVE) &&
|
||||
pdb_get_dirdrive(sampass) &&
|
||||
pdb_get_dir_drive(sampass) &&
|
||||
strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE),
|
||||
pdb_get_dirdrive(sampass)))) {
|
||||
pdb_get_dir_drive(sampass)))) {
|
||||
need_to_modify = True;
|
||||
set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dirdrive(sampass),
|
||||
strlen(pdb_get_dirdrive(sampass)), EN_MODIFIED);
|
||||
set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dir_drive(sampass),
|
||||
strlen(pdb_get_dir_drive(sampass)), EN_MODIFIED);
|
||||
}
|
||||
|
||||
/* logon_script */
|
||||
@ -860,7 +860,7 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
|
||||
set_single_attribute(obj, NPF_HOME_DIR,
|
||||
homedir, strlen(homedir), 0);
|
||||
|
||||
if(!(dirdrive = pdb_get_dirdrive(sampass)))
|
||||
if(!(dirdrive = pdb_get_dir_drive(sampass)))
|
||||
dirdrive = empty;
|
||||
|
||||
set_single_attribute(obj, NPF_DIR_DRIVE,
|
||||
@ -1032,7 +1032,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname)
|
||||
Routine to search the nisplus passwd file for an entry matching the username
|
||||
*************************************************************************/
|
||||
|
||||
BOOL pdb_getsampwsid(SAM_ACCOUNT * user, DOM_SID *sid)
|
||||
BOOL pdb_getsampwsid(SAM_ACCOUNT * user, const DOM_SID *sid)
|
||||
{
|
||||
uint32 rid;
|
||||
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
|
||||
|
@ -1149,7 +1149,7 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
|
||||
uid = pdb_get_uid(sampass);
|
||||
|
||||
/* If the user specified a RID, make sure its able to be both stored and retreived */
|
||||
if (rid && uid != fallback_pdb_user_rid_to_uid(rid)) {
|
||||
if (rid && rid != DOMAIN_USER_RID_GUEST && uid != fallback_pdb_user_rid_to_uid(rid)) {
|
||||
DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
|
||||
return False;
|
||||
}
|
||||
@ -1417,7 +1417,7 @@ static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *s
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
|
||||
static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
|
||||
{
|
||||
uint32 rid;
|
||||
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
|
||||
|
@ -354,7 +354,8 @@ static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state,
|
||||
* Only updates fields which have been set (not defaults from smb.conf)
|
||||
*/
|
||||
|
||||
if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE)) dir_drive = pdb_get_dirdrive(sampass);
|
||||
if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE))
|
||||
dir_drive = pdb_get_dir_drive(sampass);
|
||||
else dir_drive = NULL;
|
||||
if (dir_drive) dir_drive_len = strlen(dir_drive) +1;
|
||||
else dir_drive_len = 0;
|
||||
@ -541,7 +542,7 @@ static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user
|
||||
/* increment to next in line */
|
||||
tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
|
||||
|
||||
/* do we have an valid interation pointer? */
|
||||
/* do we have an valid iteration pointer? */
|
||||
if(tdb_state->passwd_tdb == NULL) {
|
||||
DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
|
||||
return False;
|
||||
@ -668,7 +669,7 @@ static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *use
|
||||
return tdbsam_getsampwnam (my_methods, user, name);
|
||||
}
|
||||
|
||||
static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
|
||||
static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
|
||||
{
|
||||
uint32 rid;
|
||||
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
|
||||
|
@ -49,23 +49,36 @@ static BOOL unixsam_getsampwrid (struct pdb_methods *methods,
|
||||
{
|
||||
struct passwd *pass;
|
||||
BOOL ret = False;
|
||||
const char *guest_account = lp_guestaccount();
|
||||
if (!(guest_account && *guest_account)) {
|
||||
DEBUG(1, ("NULL guest account!?!?\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!methods) {
|
||||
DEBUG(0,("invalid methods\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (pdb_rid_is_user(rid)) {
|
||||
pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid));
|
||||
|
||||
if (pass) {
|
||||
ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
|
||||
passwd_free(&pass);
|
||||
|
||||
if (rid == DOMAIN_USER_RID_GUEST) {
|
||||
pass = getpwnam_alloc(guest_account);
|
||||
if (!pass) {
|
||||
DEBUG(1, ("guest account %s does not seem to exist...\n", guest_account));
|
||||
return False;
|
||||
}
|
||||
} else if (pdb_rid_is_user(rid)) {
|
||||
pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid));
|
||||
} else {
|
||||
return False;
|
||||
}
|
||||
|
||||
ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
|
||||
passwd_free(&pass);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
|
||||
static BOOL unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
|
||||
{
|
||||
uint32 rid;
|
||||
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
|
||||
|
@ -128,6 +128,47 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL secrets_store_domain_guid(char *domain, GUID *guid)
|
||||
{
|
||||
fstring key;
|
||||
|
||||
slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
|
||||
strupper(key);
|
||||
return secrets_store(key, guid, sizeof(GUID));
|
||||
}
|
||||
|
||||
BOOL secrets_fetch_domain_guid(char *domain, GUID *guid)
|
||||
{
|
||||
GUID *dyn_guid;
|
||||
fstring key;
|
||||
size_t size;
|
||||
GUID new_guid;
|
||||
|
||||
slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
|
||||
strupper(key);
|
||||
dyn_guid = (GUID *)secrets_fetch(key, &size);
|
||||
|
||||
DEBUG(6,("key is %s, guid is at %x, size is %d\n", key, dyn_guid, size));
|
||||
|
||||
if ((NULL == dyn_guid) && (ROLE_DOMAIN_PDC == lp_server_role())) {
|
||||
uuid_generate_random(&new_guid);
|
||||
if (!secrets_store_domain_guid(domain, &new_guid))
|
||||
return False;
|
||||
dyn_guid = (GUID *)secrets_fetch(key, &size);
|
||||
if (dyn_guid == NULL)
|
||||
return False;
|
||||
}
|
||||
|
||||
if (size != sizeof(GUID))
|
||||
{
|
||||
SAFE_FREE(dyn_guid);
|
||||
return False;
|
||||
}
|
||||
|
||||
*guid = *dyn_guid;
|
||||
SAFE_FREE(dyn_guid);
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form a key for fetching the machine trust account password
|
||||
@ -178,7 +219,7 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16],
|
||||
if (plaintext) {
|
||||
/* we have an ADS password - use that */
|
||||
DEBUG(4,("Using ADS machine password\n"));
|
||||
E_md4hash((uchar *)plaintext, ret_pwd);
|
||||
E_md4hash(plaintext, ret_pwd);
|
||||
SAFE_FREE(plaintext);
|
||||
return True;
|
||||
}
|
||||
@ -388,7 +429,9 @@ BOOL secrets_store_ldap_pw(const char* dn, char* pw)
|
||||
|
||||
|
||||
/**
|
||||
* The linked list is allocated on the supplied talloc context, caller gets to destory
|
||||
* Get trusted domains info from secrets.tdb.
|
||||
*
|
||||
* The linked list is allocated on the supplied talloc context, caller gets to destroy
|
||||
* when done.
|
||||
*
|
||||
* @param ctx Allocation context
|
||||
@ -409,10 +452,11 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
|
||||
int start_idx;
|
||||
uint32 idx = 0;
|
||||
size_t size;
|
||||
fstring dom_name;
|
||||
struct trusted_dom_pass *pass;
|
||||
NTSTATUS status;
|
||||
|
||||
secrets_init();
|
||||
if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
|
||||
|
||||
*num_domains = 0;
|
||||
start_idx = *enum_ctx;
|
||||
@ -455,6 +499,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
|
||||
SAFE_FREE(pass);
|
||||
continue;
|
||||
}
|
||||
|
||||
pull_ucs2_fstring(dom_name, pass->uni_name);
|
||||
DEBUG(18, ("Fetched secret record num %d.\nDomain name: %s, SID: %s\n",
|
||||
idx, dom_name, sid_string_static(&pass->domain_sid)));
|
||||
|
||||
SAFE_FREE(secrets_key);
|
||||
|
||||
@ -475,6 +523,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
|
||||
dom->name = talloc_strdup_w(ctx, pass->uni_name);
|
||||
|
||||
(*domains)[idx - start_idx] = dom;
|
||||
|
||||
DEBUG(18, ("Secret record is in required range.\n \
|
||||
start_idx = %d, max_num_domains = %d. Added to returned array.\n",
|
||||
start_idx, max_num_domains));
|
||||
|
||||
*enum_ctx = idx + 1;
|
||||
(*num_domains)++;
|
||||
@ -487,6 +539,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
|
||||
/* this is the last entry in the whole enumeration */
|
||||
status = NT_STATUS_OK;
|
||||
}
|
||||
} else {
|
||||
DEBUG(18, ("Secret is outside the required range.\n \
|
||||
start_idx = %d, max_num_domains = %d. Not added to returned array\n",
|
||||
start_idx, max_num_domains));
|
||||
}
|
||||
|
||||
idx++;
|
||||
|
@ -95,6 +95,9 @@ static void init_sid_name_map (void)
|
||||
|
||||
if ((lp_security() == SEC_USER) && lp_domain_logons()) {
|
||||
sid_name_map[i].sid = get_global_sam_sid();
|
||||
/* This is not lp_workgroup() for good reason:
|
||||
it must stay around longer than the lp_*()
|
||||
strings do */
|
||||
sid_name_map[i].name = global_myworkgroup;
|
||||
sid_name_map[i].known_users = NULL;
|
||||
i++;
|
||||
|
@ -241,15 +241,12 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
|
||||
Scan printcap file pszPrintcapname for a printer called pszPrintername.
|
||||
Return True if found, else False. Returns False on error, too, after logging
|
||||
the error at level 0. For generality, the printcap name may be passed - if
|
||||
passed as NULL, the configuration will be queried for the name. pszPrintername
|
||||
must be in DOS codepage.
|
||||
The xxx_printername_ok functions need fixing to understand they are being
|
||||
given a DOS codepage. FIXME !! JRA.
|
||||
passed as NULL, the configuration will be queried for the name.
|
||||
***************************************************************************/
|
||||
BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
|
||||
BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname)
|
||||
{
|
||||
char *line=NULL;
|
||||
char *psz;
|
||||
const char *psz;
|
||||
char *p,*q;
|
||||
XFILE *pfile;
|
||||
|
||||
@ -305,8 +302,6 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
|
||||
|
||||
if (strequal(p,pszPrintername))
|
||||
{
|
||||
/* normalise the case */
|
||||
pstrcpy(pszPrintername,p);
|
||||
SAFE_FREE(line);
|
||||
x_fclose(pfile);
|
||||
return(True);
|
||||
|
@ -126,7 +126,7 @@ void sysv_printer_fn(void (*fn)(char *, char *))
|
||||
* provide the equivalent of pcap_printername_ok() for SVID/XPG4 conforming
|
||||
* systems.
|
||||
*/
|
||||
int sysv_printername_ok(char *name)
|
||||
int sysv_printername_ok(const char *name)
|
||||
{
|
||||
printer_t *tmp;
|
||||
|
||||
|
@ -54,7 +54,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
|
||||
|
||||
/* setup a full fsp */
|
||||
fsp->print_jobid = jobid;
|
||||
fsp->fd = print_job_fd(jobid);
|
||||
fsp->fd = print_job_fd(SNUM(conn),jobid);
|
||||
GetTimeOfDay(&fsp->open_time);
|
||||
fsp->vuid = current_user.vuid;
|
||||
fsp->size = 0;
|
||||
@ -70,7 +70,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
|
||||
fsp->is_directory = False;
|
||||
fsp->directory_delete_on_close = False;
|
||||
fsp->conn = conn;
|
||||
string_set(&fsp->fsp_name,print_job_fname(jobid));
|
||||
string_set(&fsp->fsp_name,print_job_fname(SNUM(conn),jobid));
|
||||
fsp->wbmpx_ptr = NULL;
|
||||
fsp->wcp = NULL;
|
||||
conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf);
|
||||
@ -96,7 +96,7 @@ void print_fsp_end(files_struct *fsp, BOOL normal_close)
|
||||
sys_ftruncate(fsp->fd, 0);
|
||||
}
|
||||
|
||||
print_job_end(fsp->print_jobid, normal_close);
|
||||
print_job_end(SNUM(fsp->conn),fsp->print_jobid, normal_close);
|
||||
|
||||
if (fsp->fsp_name) {
|
||||
string_free(&fsp->fsp_name);
|
||||
|
@ -39,98 +39,97 @@ static struct printif *current_printif = &generic_printif;
|
||||
jobids are assigned when a job starts spooling.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
|
||||
bit RPC jobids.... JRA.
|
||||
***************************************************************************/
|
||||
|
||||
static TDB_CONTEXT *rap_tdb;
|
||||
static uint16 next_rap_jobid;
|
||||
|
||||
uint16 pjobid_to_rap(int snum, uint32 jobid)
|
||||
{
|
||||
uint16 rap_jobid;
|
||||
TDB_DATA data, key;
|
||||
char jinfo[8];
|
||||
|
||||
if (!rap_tdb) {
|
||||
/* Create the in-memory tdb. */
|
||||
rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
|
||||
if (!rap_tdb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SIVAL(&jinfo,0,(int32)snum);
|
||||
SIVAL(&jinfo,4,jobid);
|
||||
|
||||
key.dptr = (char *)&jinfo;
|
||||
key.dsize = sizeof(jinfo);
|
||||
data = tdb_fetch(rap_tdb, key);
|
||||
if (data.dptr && data.dsize == sizeof(uint16)) {
|
||||
memcpy(&rap_jobid, data.dptr, sizeof(uint16));
|
||||
SAFE_FREE(data.dptr);
|
||||
return rap_jobid;
|
||||
}
|
||||
/* Not found - create and store mapping. */
|
||||
rap_jobid = ++next_rap_jobid;
|
||||
if (rap_jobid == 0)
|
||||
rap_jobid = ++next_rap_jobid;
|
||||
data.dptr = (char *)&rap_jobid;
|
||||
data.dsize = sizeof(rap_jobid);
|
||||
tdb_store(rap_tdb, key, data, TDB_REPLACE);
|
||||
tdb_store(rap_tdb, data, key, TDB_REPLACE);
|
||||
return rap_jobid;
|
||||
}
|
||||
|
||||
BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
|
||||
{
|
||||
TDB_DATA data, key;
|
||||
char jinfo[8];
|
||||
|
||||
if (!rap_tdb)
|
||||
return False;
|
||||
|
||||
key.dptr = (char *)&rap_jobid;
|
||||
key.dsize = sizeof(rap_jobid);
|
||||
data = tdb_fetch(rap_tdb, key);
|
||||
if (data.dptr && data.dsize == sizeof(jinfo)) {
|
||||
*psnum = IVAL(&jinfo,0);
|
||||
*pjobid = IVAL(&jinfo,4);
|
||||
SAFE_FREE(data.dptr);
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static void rap_jobid_delete(int snum, uint32 jobid)
|
||||
{
|
||||
TDB_DATA key, data;
|
||||
uint16 rap_jobid;
|
||||
char jinfo[8];
|
||||
|
||||
if (!rap_tdb)
|
||||
return;
|
||||
|
||||
SIVAL(&jinfo,0,(int32)snum);
|
||||
SIVAL(&jinfo,4,jobid);
|
||||
|
||||
key.dptr = (char *)&jinfo;
|
||||
key.dsize = sizeof(jinfo);
|
||||
data = tdb_fetch(rap_tdb, key);
|
||||
if (!data.dptr || (data.dsize != sizeof(uint16)))
|
||||
return;
|
||||
|
||||
memcpy(&rap_jobid, data.dptr, sizeof(uint16));
|
||||
SAFE_FREE(data.dptr);
|
||||
data.dptr = (char *)&rap_jobid;
|
||||
data.dsize = sizeof(rap_jobid);
|
||||
tdb_delete(rap_tdb, key);
|
||||
tdb_delete(rap_tdb, data);
|
||||
}
|
||||
|
||||
static pid_t local_pid;
|
||||
|
||||
/* Mapping between printer names and queue id's in job id's. */
|
||||
struct printer_queueid_map {
|
||||
struct printer_queueid_map *next, *prev;
|
||||
char *printername;
|
||||
uint32 queueid;
|
||||
};
|
||||
|
||||
static struct printer_queueid_map *printer_queueid_map_head;
|
||||
static uint32 last_queueid;
|
||||
|
||||
#define QUEUEID_BITS 12
|
||||
#define QUEUEID_MASK ((1<<(QUEUEID_BITS))-1)
|
||||
#define QUEUEID_TO_JOBID(queueid) (((queueid) & QUEUEID_MASK) << 20 )
|
||||
|
||||
/****************************************************************************
|
||||
Create an association between a printer name and a queueid. Used to encode
|
||||
the printer queueid in jobid's.
|
||||
This could be converted to use an internal tdb if searching the list is
|
||||
too slow. JRA.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL create_printer_queueid(const char *printername)
|
||||
{
|
||||
struct printer_queueid_map *p;
|
||||
|
||||
for (p = printer_queueid_map_head; p; p = p->next) {
|
||||
if (strequal(p->printername, printername))
|
||||
return True;
|
||||
}
|
||||
|
||||
p = (struct printer_queueid_map *)malloc(sizeof(*p));
|
||||
if (!p) {
|
||||
DEBUG(0,("create_printer_queueid: malloc fail !\n"));
|
||||
return False;
|
||||
}
|
||||
ZERO_STRUCTP(p);
|
||||
p->printername = strdup(printername);
|
||||
if (!p->printername) {
|
||||
DEBUG(0,("create_printer_queueid: malloc fail !\n"));
|
||||
SAFE_FREE(p);
|
||||
return False;
|
||||
}
|
||||
p->queueid = (++last_queueid);
|
||||
if (p->queueid > QUEUEID_MASK) {
|
||||
DEBUG(0,("create_printer_queueid: malloc fail !\n"));
|
||||
SAFE_FREE(p->printername);
|
||||
SAFE_FREE(p);
|
||||
return False;
|
||||
}
|
||||
DLIST_ADD(printer_queueid_map_head, p);
|
||||
return True;
|
||||
}
|
||||
|
||||
void set_register_printer_fn(void)
|
||||
{
|
||||
extern BOOL (*register_printer_fn)(const char *);
|
||||
register_printer_fn = create_printer_queueid;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Lookups.
|
||||
****************************************************************************/
|
||||
|
||||
static uint32 get_printer_queueid_byname(const char *printername)
|
||||
{
|
||||
struct printer_queueid_map *p;
|
||||
|
||||
for (p = printer_queueid_map_head; p; p = p->next) {
|
||||
if (strequal(p->printername, printername))
|
||||
return p->queueid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Lookups.
|
||||
****************************************************************************/
|
||||
|
||||
static const char *get_printer_name_byjobid(uint32 jobid)
|
||||
{
|
||||
struct printer_queueid_map *p;
|
||||
uint32 queueid = (((jobid)>>20) & QUEUEID_MASK);
|
||||
|
||||
for (p = printer_queueid_map_head; p; p = p->next) {
|
||||
if (p->queueid == queueid)
|
||||
return p->printername;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int get_queue_status(int, print_status_struct *);
|
||||
|
||||
#define MAX_PRINT_DBS_OPEN 1
|
||||
@ -186,9 +185,14 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
|
||||
DLIST_ADD(print_db_head, p);
|
||||
}
|
||||
|
||||
pstrcpy(printdb_path, lock_path(printername));
|
||||
pstrcpy(printdb_path, lock_path("printing/"));
|
||||
pstrcat(printdb_path, printername);
|
||||
pstrcat(printdb_path, ".tdb");
|
||||
|
||||
become_root();
|
||||
p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
|
||||
unbecome_root();
|
||||
|
||||
if (!p->tdb) {
|
||||
DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
|
||||
printdb_path ));
|
||||
@ -200,14 +204,6 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
|
||||
return p;
|
||||
}
|
||||
|
||||
static struct tdb_print_db *get_print_db_byjobid( uint32 jobid)
|
||||
{
|
||||
const char *printername = get_printer_name_byjobid(jobid);
|
||||
if (!printername)
|
||||
return NULL;
|
||||
return get_print_db_byname(printername);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Initialise the printing backend. Called once at startup.
|
||||
Does not survive a fork
|
||||
@ -215,20 +211,28 @@ static struct tdb_print_db *get_print_db_byjobid( uint32 jobid)
|
||||
|
||||
BOOL print_backend_init(void)
|
||||
{
|
||||
struct printer_queueid_map *p;
|
||||
char *sversion = "INFO/version";
|
||||
pstring printing_path;
|
||||
int services = lp_numservices();
|
||||
int snum;
|
||||
|
||||
if (local_pid == sys_getpid())
|
||||
return True;
|
||||
|
||||
unlink(lock_path("printing.tdb"));
|
||||
pstrcpy(printing_path,lock_path("printing"));
|
||||
mkdir(printing_path,0755);
|
||||
|
||||
local_pid = sys_getpid();
|
||||
|
||||
/* handle a Samba upgrade */
|
||||
|
||||
for (p = printer_queueid_map_head; p; p = p->next) {
|
||||
struct tdb_print_db *pdb = get_print_db_byname(p->printername);
|
||||
for (snum = 0; snum < services; snum++) {
|
||||
struct tdb_print_db *pdb;
|
||||
if (!lp_print_ok(snum))
|
||||
continue;
|
||||
|
||||
pdb = get_print_db_byname(lp_const_servicename(snum));
|
||||
if (!pdb)
|
||||
continue;
|
||||
tdb_lock_bystring(pdb->tdb, sversion);
|
||||
@ -286,11 +290,11 @@ static TDB_DATA print_key(uint32 jobid)
|
||||
Useful function to find a print job in the database.
|
||||
****************************************************************************/
|
||||
|
||||
static struct printjob *print_job_find(uint32 jobid)
|
||||
static struct printjob *print_job_find(int snum, uint32 jobid)
|
||||
{
|
||||
static struct printjob pjob;
|
||||
TDB_DATA ret;
|
||||
struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
|
||||
struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
|
||||
|
||||
if (!pdb)
|
||||
return NULL;
|
||||
@ -334,11 +338,16 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
|
||||
|
||||
uint32 sysjob_to_jobid(int unix_jobid)
|
||||
{
|
||||
struct printer_queueid_map *p;
|
||||
int services = lp_numservices();
|
||||
int snum;
|
||||
|
||||
sysjob_to_jobid_value = (uint32)-1;
|
||||
|
||||
for (p = printer_queueid_map_head; p; p = p->next) {
|
||||
struct tdb_print_db *pdb = get_print_db_byname(p->printername);
|
||||
for (snum = 0; snum < services; snum++) {
|
||||
struct tdb_print_db *pdb;
|
||||
if (!lp_print_ok(snum))
|
||||
continue;
|
||||
pdb = get_print_db_byname(lp_const_servicename(snum));
|
||||
if (pdb)
|
||||
tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
|
||||
if (sysjob_to_jobid_value != (uint32)-1)
|
||||
@ -385,14 +394,10 @@ static uint32 map_to_spoolss_status(uint32 lpq_status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pjob_store_notify(uint32 jobid, struct printjob *old_data,
|
||||
static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
|
||||
struct printjob *new_data)
|
||||
{
|
||||
BOOL new_job = False;
|
||||
int snum = print_job_snum(jobid);
|
||||
|
||||
if (snum == -1)
|
||||
return;
|
||||
|
||||
if (!old_data)
|
||||
new_job = True;
|
||||
@ -427,11 +432,11 @@ static void pjob_store_notify(uint32 jobid, struct printjob *old_data,
|
||||
Store a job structure back to the database.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL pjob_store(uint32 jobid, struct printjob *pjob)
|
||||
static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
|
||||
{
|
||||
TDB_DATA old_data, new_data;
|
||||
BOOL ret;
|
||||
struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
|
||||
struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
|
||||
|
||||
if (!pdb)
|
||||
return False;
|
||||
@ -450,7 +455,7 @@ static BOOL pjob_store(uint32 jobid, struct printjob *pjob)
|
||||
|
||||
if (ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob))) {
|
||||
pjob_store_notify(
|
||||
jobid, (struct printjob *)old_data.dptr,
|
||||
snum, jobid, (struct printjob *)old_data.dptr,
|
||||
(struct printjob *)new_data.dptr);
|
||||
free(old_data.dptr);
|
||||
}
|
||||
@ -462,12 +467,11 @@ static BOOL pjob_store(uint32 jobid, struct printjob *pjob)
|
||||
Remove a job structure from the database.
|
||||
****************************************************************************/
|
||||
|
||||
static void pjob_delete(uint32 jobid)
|
||||
static void pjob_delete(int snum, uint32 jobid)
|
||||
{
|
||||
int snum;
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
uint32 job_status = 0;
|
||||
struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
|
||||
struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
|
||||
|
||||
if (!pdb)
|
||||
return;
|
||||
@ -486,7 +490,6 @@ static void pjob_delete(uint32 jobid)
|
||||
JOB_STATUS_DELETED for the port monitor to delete the job
|
||||
properly. */
|
||||
|
||||
snum = print_job_snum(jobid);
|
||||
job_status |= JOB_STATUS_DELETING;
|
||||
notify_job_status(snum, jobid, job_status);
|
||||
|
||||
@ -496,6 +499,7 @@ static void pjob_delete(uint32 jobid)
|
||||
/* Remove from printing.tdb */
|
||||
|
||||
tdb_delete(pdb->tdb, print_key(jobid));
|
||||
rap_jobid_delete(snum, jobid);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -523,13 +527,12 @@ static uint32 print_parse_jobid(char *fname)
|
||||
|
||||
static void print_unix_job(int snum, print_queue_struct *q)
|
||||
{
|
||||
uint32 queueid = get_printer_queueid_byname(PRINTERNAME(snum));
|
||||
uint32 jobid = (q->job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid);
|
||||
uint32 jobid = q->job + UNIX_JOB_START;
|
||||
struct printjob pj, *old_pj;
|
||||
|
||||
/* Preserve the timestamp on an existing unix print job */
|
||||
|
||||
old_pj = print_job_find(jobid);
|
||||
old_pj = print_job_find(snum, jobid);
|
||||
|
||||
ZERO_STRUCT(pj);
|
||||
|
||||
@ -546,7 +549,7 @@ static void print_unix_job(int snum, print_queue_struct *q)
|
||||
fstrcpy(pj.user, q->fs_user);
|
||||
fstrcpy(pj.queuename, lp_const_servicename(snum));
|
||||
|
||||
pjob_store(jobid, &pj);
|
||||
pjob_store(snum, jobid, &pj);
|
||||
}
|
||||
|
||||
|
||||
@ -561,7 +564,6 @@ struct traverse_struct {
|
||||
|
||||
static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
|
||||
{
|
||||
uint32 queueid;
|
||||
struct traverse_struct *ts = (struct traverse_struct *)state;
|
||||
struct printjob pjob;
|
||||
uint32 jobid;
|
||||
@ -577,18 +579,16 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
|
||||
return 0;
|
||||
}
|
||||
|
||||
queueid = get_printer_queueid_byname(pjob.queuename);
|
||||
|
||||
if (!pjob.smbjob) {
|
||||
/* remove a unix job if it isn't in the system queue any more */
|
||||
|
||||
for (i=0;i<ts->qcount;i++) {
|
||||
uint32 u_jobid = ((ts->queue[i].job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid));
|
||||
uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
|
||||
if (jobid == u_jobid)
|
||||
break;
|
||||
}
|
||||
if (i == ts->qcount)
|
||||
pjob_delete(jobid);
|
||||
pjob_delete(ts->snum, jobid);
|
||||
else
|
||||
ts->total_jobs++;
|
||||
return 0;
|
||||
@ -600,14 +600,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
|
||||
exist then kill it. This cleans up after smbd
|
||||
deaths */
|
||||
if (!process_exists(pjob.pid))
|
||||
pjob_delete(jobid);
|
||||
pjob_delete(ts->snum, jobid);
|
||||
else
|
||||
ts->total_jobs++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0;i<ts->qcount;i++) {
|
||||
uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file) | QUEUEID_TO_JOBID(queueid);
|
||||
uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
|
||||
if (jobid == curr_jobid)
|
||||
break;
|
||||
}
|
||||
@ -627,7 +627,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
|
||||
submitted less than lp_lpqcachetime() seconds ago. */
|
||||
|
||||
if ((cur_t - pjob.starttime) > lp_lpqcachetime())
|
||||
pjob_delete(jobid);
|
||||
pjob_delete(ts->snum, jobid);
|
||||
else
|
||||
ts->total_jobs++;
|
||||
}
|
||||
@ -688,7 +688,7 @@ static pid_t get_updating_pid(fstring printer_name)
|
||||
in the tdb.
|
||||
****************************************************************************/
|
||||
|
||||
static void set_updating_pid(fstring printer_name, BOOL delete)
|
||||
static void set_updating_pid(const fstring printer_name, BOOL delete)
|
||||
{
|
||||
fstring keystr;
|
||||
TDB_DATA key;
|
||||
@ -813,7 +813,7 @@ static void print_queue_update(int snum)
|
||||
}
|
||||
|
||||
/* we have an active SMB print job - update its status */
|
||||
pjob = print_job_find(jobid);
|
||||
pjob = print_job_find(snum, jobid);
|
||||
if (!pjob) {
|
||||
/* err, somethings wrong. Probably smbd was restarted
|
||||
with jobs in the queue. All we can do is treat them
|
||||
@ -825,7 +825,7 @@ static void print_queue_update(int snum)
|
||||
pjob->sysjob = queue[i].job;
|
||||
pjob->status = queue[i].status;
|
||||
|
||||
pjob_store(jobid, pjob);
|
||||
pjob_store(snum, jobid, pjob);
|
||||
}
|
||||
|
||||
/* now delete any queued entries that don't appear in the
|
||||
@ -871,36 +871,21 @@ static void print_queue_update(int snum)
|
||||
Check if a jobid is valid. It is valid if it exists in the database.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL print_job_exists(uint32 jobid)
|
||||
BOOL print_job_exists(int snum, uint32 jobid)
|
||||
{
|
||||
struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
|
||||
struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
|
||||
if (!pdb)
|
||||
return False;
|
||||
return tdb_exists(pdb->tdb, print_key(jobid));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Work out which service a jobid is for.
|
||||
Note that we have to look up by queue name to ensure that it works for
|
||||
other than the process that started the job.
|
||||
****************************************************************************/
|
||||
|
||||
int print_job_snum(uint32 jobid)
|
||||
{
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
if (!pjob)
|
||||
return -1;
|
||||
|
||||
return find_service(pjob->queuename);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Give the fd used for a jobid.
|
||||
****************************************************************************/
|
||||
|
||||
int print_job_fd(uint32 jobid)
|
||||
int print_job_fd(int snum, uint32 jobid)
|
||||
{
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
if (!pjob)
|
||||
return -1;
|
||||
/* don't allow another process to get this info - it is meaningless */
|
||||
@ -915,9 +900,9 @@ int print_job_fd(uint32 jobid)
|
||||
has not been spooled.
|
||||
****************************************************************************/
|
||||
|
||||
char *print_job_fname(uint32 jobid)
|
||||
char *print_job_fname(int snum, uint32 jobid)
|
||||
{
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
if (!pjob || pjob->spooled || pjob->pid != local_pid)
|
||||
return NULL;
|
||||
return pjob->filename;
|
||||
@ -927,7 +912,7 @@ char *print_job_fname(uint32 jobid)
|
||||
Set the place in the queue for a job.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL print_job_set_place(uint32 jobid, int place)
|
||||
BOOL print_job_set_place(int snum, uint32 jobid, int place)
|
||||
{
|
||||
DEBUG(2,("print_job_set_place not implemented yet\n"));
|
||||
return False;
|
||||
@ -937,24 +922,24 @@ BOOL print_job_set_place(uint32 jobid, int place)
|
||||
Set the name of a job. Only possible for owner.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL print_job_set_name(uint32 jobid, char *name)
|
||||
BOOL print_job_set_name(int snum, uint32 jobid, char *name)
|
||||
{
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
if (!pjob || pjob->pid != local_pid)
|
||||
return False;
|
||||
|
||||
fstrcpy(pjob->jobname, name);
|
||||
return pjob_store(jobid, pjob);
|
||||
return pjob_store(snum, jobid, pjob);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Delete a print job - don't update queue.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL print_job_delete1(uint32 jobid)
|
||||
static BOOL print_job_delete1(int snum, uint32 jobid)
|
||||
{
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
int snum, result = 0;
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
int result = 0;
|
||||
|
||||
if (!pjob)
|
||||
return False;
|
||||
@ -966,12 +951,6 @@ static BOOL print_job_delete1(uint32 jobid)
|
||||
if (pjob->status == LPQ_DELETING)
|
||||
return True;
|
||||
|
||||
snum = print_job_snum(jobid);
|
||||
if (snum == -1) {
|
||||
DEBUG(5,("print_job_delete1: unknown service number for jobid %u\n", (unsigned int)jobid));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Hrm - we need to be able to cope with deleting a job before it
|
||||
has reached the spooler. */
|
||||
|
||||
@ -982,7 +961,7 @@ static BOOL print_job_delete1(uint32 jobid)
|
||||
/* Set the tdb entry to be deleting. */
|
||||
|
||||
pjob->status = LPQ_DELETING;
|
||||
pjob_store(jobid, pjob);
|
||||
pjob_store(snum, jobid, pjob);
|
||||
|
||||
if (pjob->spooled && pjob->sysjob != -1)
|
||||
result = (*(current_printif->job_delete))(snum, pjob);
|
||||
@ -991,7 +970,7 @@ static BOOL print_job_delete1(uint32 jobid)
|
||||
been spooled. */
|
||||
|
||||
if (result == 0)
|
||||
pjob_delete(jobid);
|
||||
pjob_delete(snum, jobid);
|
||||
|
||||
return (result == 0);
|
||||
}
|
||||
@ -1000,9 +979,9 @@ static BOOL print_job_delete1(uint32 jobid)
|
||||
Return true if the current user owns the print job.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL is_owner(struct current_user *user, uint32 jobid)
|
||||
static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
|
||||
{
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
user_struct *vuser;
|
||||
|
||||
if (!pjob || !user)
|
||||
@ -1019,17 +998,11 @@ static BOOL is_owner(struct current_user *user, uint32 jobid)
|
||||
Delete a print job.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode)
|
||||
BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
|
||||
{
|
||||
int snum = print_job_snum(jobid);
|
||||
BOOL owner;
|
||||
|
||||
if (snum == -1) {
|
||||
DEBUG(5,("print_job_delete: unknown service number for jobid %d\n", jobid));
|
||||
return False;
|
||||
}
|
||||
|
||||
owner = is_owner(user, jobid);
|
||||
owner = is_owner(user, snum, jobid);
|
||||
|
||||
/* Check access against security descriptor or whether the user
|
||||
owns their job. */
|
||||
@ -1041,7 +1014,7 @@ BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode)
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!print_job_delete1(jobid))
|
||||
if (!print_job_delete1(snum, jobid))
|
||||
return False;
|
||||
|
||||
/* force update the database and say the delete failed if the
|
||||
@ -1049,17 +1022,17 @@ BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode)
|
||||
|
||||
print_queue_update(snum);
|
||||
|
||||
return !print_job_exists(jobid);
|
||||
return !print_job_exists(snum, jobid);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Pause a job.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode)
|
||||
BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
|
||||
{
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
int snum, ret = -1;
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
int ret = -1;
|
||||
|
||||
if (!pjob || !user)
|
||||
return False;
|
||||
@ -1067,13 +1040,7 @@ BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode)
|
||||
if (!pjob->spooled || pjob->sysjob == -1)
|
||||
return False;
|
||||
|
||||
snum = print_job_snum(jobid);
|
||||
if (snum == -1) {
|
||||
DEBUG(5,("print_job_pause: unknown service number for jobid %u\n", (unsigned int)jobid));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!is_owner(user, jobid) &&
|
||||
if (!is_owner(user, snum, jobid) &&
|
||||
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
|
||||
DEBUG(3, ("pause denied by security descriptor\n"));
|
||||
*errcode = WERR_ACCESS_DENIED;
|
||||
@ -1104,10 +1071,10 @@ BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode)
|
||||
Resume a job.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode)
|
||||
BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
|
||||
{
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
int snum, ret;
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
int ret;
|
||||
|
||||
if (!pjob || !user)
|
||||
return False;
|
||||
@ -1115,13 +1082,7 @@ BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode)
|
||||
if (!pjob->spooled || pjob->sysjob == -1)
|
||||
return False;
|
||||
|
||||
snum = print_job_snum(jobid);
|
||||
if (snum == -1) {
|
||||
DEBUG(5,("print_job_resume: unknown service number for jobid %u\n", (unsigned int)jobid));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!is_owner(user, jobid) &&
|
||||
if (!is_owner(user, snum, jobid) &&
|
||||
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
|
||||
DEBUG(3, ("resume denied by security descriptor\n"));
|
||||
*errcode = WERR_ACCESS_DENIED;
|
||||
@ -1149,10 +1110,10 @@ BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode)
|
||||
Write to a print file.
|
||||
****************************************************************************/
|
||||
|
||||
int print_job_write(uint32 jobid, const char *buf, int size)
|
||||
int print_job_write(int snum, uint32 jobid, const char *buf, int size)
|
||||
{
|
||||
int return_code;
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
|
||||
if (!pjob)
|
||||
return -1;
|
||||
@ -1163,7 +1124,7 @@ int print_job_write(uint32 jobid, const char *buf, int size)
|
||||
return_code = write(pjob->fd, buf, size);
|
||||
if (return_code>0) {
|
||||
pjob->size += size;
|
||||
pjob_store(jobid, pjob);
|
||||
pjob_store(snum, jobid, pjob);
|
||||
}
|
||||
return return_code;
|
||||
}
|
||||
@ -1260,18 +1221,24 @@ int print_queue_length(int snum, print_status_struct *pstatus)
|
||||
|
||||
static int get_total_jobs(void)
|
||||
{
|
||||
int total_jobs;
|
||||
struct printer_queueid_map *p;
|
||||
int total_jobs = 0;
|
||||
int snum;
|
||||
int services = lp_numservices();
|
||||
|
||||
for (p = printer_queueid_map_head; p; p = p->next) {
|
||||
for (snum = 0; snum < services; snum++) {
|
||||
struct tdb_print_db *pdb;
|
||||
int jobs;
|
||||
struct tdb_print_db *pdb = get_print_db_byname(p->printername);
|
||||
|
||||
if (!lp_print_ok(snum))
|
||||
continue;
|
||||
|
||||
pdb = get_print_db_byname(lp_const_servicename(snum));
|
||||
if (!pdb)
|
||||
continue;
|
||||
|
||||
/* make sure the database is up to date */
|
||||
if (print_cache_expired(lp_servicenumber(p->printername)))
|
||||
print_queue_update(lp_servicenumber(p->printername));
|
||||
if (print_cache_expired(snum))
|
||||
print_queue_update(snum);
|
||||
|
||||
jobs = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
|
||||
if (jobs > 0)
|
||||
@ -1294,7 +1261,6 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
|
||||
int njobs = 0;
|
||||
const char *printername = lp_const_servicename(snum);
|
||||
struct tdb_print_db *pdb = get_print_db_byname(printername);
|
||||
uint32 queueid = queueid = get_printer_queueid_byname(printername);
|
||||
|
||||
errno = 0;
|
||||
|
||||
@ -1376,10 +1342,10 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
|
||||
next_jobid = 1;
|
||||
|
||||
for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
|
||||
if (!print_job_exists(jobid | QUEUEID_TO_JOBID(queueid)))
|
||||
if (!print_job_exists(snum, jobid))
|
||||
break;
|
||||
}
|
||||
if (jobid == next_jobid || !pjob_store(jobid | QUEUEID_TO_JOBID(queueid), &pjob)) {
|
||||
if (jobid == next_jobid || !pjob_store(snum, jobid, &pjob)) {
|
||||
DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n",
|
||||
jobid, next_jobid ));
|
||||
jobid = -1;
|
||||
@ -1392,9 +1358,6 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Ensure the queuid is added to the jobid. */
|
||||
jobid |= QUEUEID_TO_JOBID(queueid);
|
||||
|
||||
/* we have a job entry - now create the spool file */
|
||||
slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
|
||||
path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
|
||||
@ -1413,7 +1376,7 @@ to open spool file %s.\n", pjob.filename));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pjob_store(jobid, &pjob);
|
||||
pjob_store(snum, jobid, &pjob);
|
||||
|
||||
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
|
||||
|
||||
@ -1425,14 +1388,14 @@ to open spool file %s.\n", pjob.filename));
|
||||
* tim@fsg.com 09/06/94
|
||||
*/
|
||||
if (lp_postscript(snum)) {
|
||||
print_job_write(jobid, "%!\n",3);
|
||||
print_job_write(snum, jobid, "%!\n",3);
|
||||
}
|
||||
|
||||
return jobid;
|
||||
|
||||
fail:
|
||||
if (jobid != -1)
|
||||
pjob_delete(jobid);
|
||||
pjob_delete(snum, jobid);
|
||||
|
||||
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
|
||||
|
||||
@ -1444,9 +1407,9 @@ to open spool file %s.\n", pjob.filename));
|
||||
Update the number of pages spooled to jobid
|
||||
****************************************************************************/
|
||||
|
||||
void print_job_endpage(uint32 jobid)
|
||||
void print_job_endpage(int snum, uint32 jobid)
|
||||
{
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
if (!pjob)
|
||||
return;
|
||||
/* don't allow another process to get this info - it is meaningless */
|
||||
@ -1454,7 +1417,7 @@ void print_job_endpage(uint32 jobid)
|
||||
return;
|
||||
|
||||
pjob->page_count++;
|
||||
pjob_store(jobid, pjob);
|
||||
pjob_store(snum, jobid, pjob);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1463,10 +1426,10 @@ void print_job_endpage(uint32 jobid)
|
||||
error.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL print_job_end(uint32 jobid, BOOL normal_close)
|
||||
BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
|
||||
{
|
||||
struct printjob *pjob = print_job_find(jobid);
|
||||
int snum, ret;
|
||||
struct printjob *pjob = print_job_find(snum, jobid);
|
||||
int ret;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
|
||||
if (!pjob)
|
||||
@ -1475,12 +1438,6 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close)
|
||||
if (pjob->spooled || pjob->pid != local_pid)
|
||||
return False;
|
||||
|
||||
snum = print_job_snum(jobid);
|
||||
if (snum == -1) {
|
||||
DEBUG(5,("print_job_end: unknown service number for jobid %u\n", (unsigned int)jobid));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
|
||||
pjob->size = sbuf.st_size;
|
||||
close(pjob->fd);
|
||||
@ -1505,7 +1462,7 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close)
|
||||
DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
|
||||
pjob->filename, pjob->size ? "deleted" : "zero length" ));
|
||||
unlink(pjob->filename);
|
||||
pjob_delete(jobid);
|
||||
pjob_delete(snum, jobid);
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -1518,7 +1475,7 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close)
|
||||
|
||||
pjob->spooled = True;
|
||||
pjob->status = LPQ_QUEUED;
|
||||
pjob_store(jobid, pjob);
|
||||
pjob_store(snum, jobid, pjob);
|
||||
|
||||
/* make sure the database is up to date */
|
||||
if (print_cache_expired(snum))
|
||||
@ -1531,7 +1488,7 @@ fail:
|
||||
/* The print job was not succesfully started. Cleanup */
|
||||
/* Still need to add proper error return propagation! 010122:JRR */
|
||||
unlink(pjob->filename);
|
||||
pjob_delete(jobid);
|
||||
pjob_delete(snum, jobid);
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -1793,10 +1750,10 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
|
||||
njobs = print_queue_status(snum, &queue, &status);
|
||||
|
||||
for (i=0;i<njobs;i++) {
|
||||
BOOL owner = is_owner(user, queue[i].job);
|
||||
BOOL owner = is_owner(user, snum, queue[i].job);
|
||||
|
||||
if (owner || can_job_admin) {
|
||||
print_job_delete1(queue[i].job);
|
||||
print_job_delete1(snum, queue[i].job);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,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) Andrew Bartlett 2002.
|
||||
* Copyright (C) Paul Ashton 1997,
|
||||
* Copyright (C) Andrew Bartlett 2002,
|
||||
* 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
|
||||
@ -2117,3 +2118,121 @@ BOOL policy_handle_is_valid(const POLICY_HND *hnd)
|
||||
ZERO_STRUCT(zero_pol);
|
||||
return ((memcmp(&zero_pol, hnd, sizeof(POLICY_HND)) == 0) ? False : True );
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes an LSA_DNS_DOM_INFO structure.
|
||||
********************************************************************/
|
||||
|
||||
BOOL lsa_io_dns_dom_info(char *desc, LSA_DNS_DOM_INFO *info,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
prs_debug(ps, depth, desc, "lsa_io_dns_dom_info");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
if(!smb_io_unihdr("nb_name", &info->hdr_nb_dom_name, ps, depth))
|
||||
return False;
|
||||
if(!smb_io_unihdr("dns_name", &info->hdr_dns_dom_name, ps, depth))
|
||||
return False;
|
||||
if(!smb_io_unihdr("forest", &info->hdr_forest_name, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
if (!prs_uint8s(False, "dom_guid", ps, depth, info->dom_guid.info, GUID_SIZE))
|
||||
return False;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
if(!prs_uint32("dom_sid", ps, depth, &info->ptr_dom_sid))
|
||||
return False;
|
||||
|
||||
if(!smb_io_unistr2("nb_name", &info->uni_nb_dom_name,
|
||||
info->hdr_nb_dom_name.buffer, ps, depth))
|
||||
return False;
|
||||
if(!smb_io_unistr2("dns_name", &info->uni_dns_dom_name,
|
||||
info->hdr_dns_dom_name.buffer, ps, depth))
|
||||
return False;
|
||||
if(!smb_io_unistr2("forest", &info->uni_forest_name,
|
||||
info->hdr_forest_name.buffer, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Inits an LSA_Q_QUERY_INFO2 structure.
|
||||
********************************************************************/
|
||||
|
||||
void init_q_query2(LSA_Q_QUERY_INFO2 *q_q, POLICY_HND *hnd, uint16 info_class)
|
||||
{
|
||||
DEBUG(5, ("init_q_query2\n"));
|
||||
|
||||
memcpy(&q_q->pol, hnd, sizeof(q_q->pol));
|
||||
|
||||
q_q->info_class = info_class;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes an LSA_Q_QUERY_DNSDOMINFO structure.
|
||||
********************************************************************/
|
||||
|
||||
BOOL lsa_io_q_query_info2(char *desc, LSA_Q_QUERY_INFO2 *q_c,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
prs_debug(ps, depth, desc, "lsa_io_q_query_info2");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!smb_io_pol_hnd("pol", &q_c->pol, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_uint16("info_class", ps, depth, &q_c->info_class))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes an LSA_R_QUERY_DNSDOMINFO structure.
|
||||
********************************************************************/
|
||||
|
||||
BOOL lsa_io_r_query_info2(char *desc, LSA_R_QUERY_INFO2 *r_c,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
prs_debug(ps, depth, desc, "lsa_io_r_query_info2");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("ptr", ps, depth, &r_c->ptr))
|
||||
return False;
|
||||
if(!prs_uint16("info_class", ps, depth, &r_c->info_class))
|
||||
return False;
|
||||
switch(r_c->info_class) {
|
||||
case 0x000c:
|
||||
if (!lsa_io_dns_dom_info("info12", &r_c->info.dns_dom_info,
|
||||
ps, depth))
|
||||
return False;
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("lsa_io_r_query_info2: unknown info class %d\n",
|
||||
r_c->info_class));
|
||||
return False;
|
||||
}
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
if(!prs_ntstatus("status", ps, depth, &r_c->status))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
@ -1335,7 +1335,7 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
|
||||
********************************************************************/
|
||||
|
||||
BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
|
||||
int depth, uint16 validation_level)
|
||||
int depth, uint16 validation_level)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -893,9 +893,11 @@ BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *
|
||||
return False;
|
||||
|
||||
if (UNMARSHALLING(ps)) {
|
||||
str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
|
||||
if (str->buffer == NULL)
|
||||
return False;
|
||||
if ( str->buf_len ) {
|
||||
str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
|
||||
if ( str->buffer == NULL )
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
p = (char *)str->buffer;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* RPC Pipe client / server routines
|
||||
* Copyright (C) Andrew Tridgell 1992-1997,
|
||||
@ -6,6 +6,7 @@
|
||||
* Copyright (C) Paul Ashton 1997.
|
||||
* Copyright (C) Marc Jacobsen 1999.
|
||||
* Copyright (C) Simo Sorce 2000.
|
||||
* Copyright (C) Gerald Carter 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
|
||||
@ -27,6 +28,89 @@
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_RPC_PARSE
|
||||
|
||||
/*******************************************************************
|
||||
Fill in a BUFFER2 for the data given a REGISTRY_VALUE
|
||||
*******************************************************************/
|
||||
|
||||
static uint32 reg_init_buffer2( BUFFER2 *buf2, REGISTRY_VALUE *val )
|
||||
{
|
||||
UNISTR2 unistr;
|
||||
uint32 real_size = 0;
|
||||
char *string;
|
||||
char *list = NULL;
|
||||
char *list2 = NULL;
|
||||
|
||||
if ( !buf2 || !val )
|
||||
return 0;
|
||||
|
||||
real_size = val->size;
|
||||
|
||||
switch (val->type )
|
||||
{
|
||||
case REG_SZ:
|
||||
string = (char*)val->data_p;
|
||||
DEBUG(10,("reg_init_buffer2: REG_SZ string => [%s]\n", string));
|
||||
|
||||
init_unistr2( &unistr, (char*)val->data_p, strlen((char*)val->data_p)+1 );
|
||||
init_buffer2( buf2, (char*)unistr.buffer, unistr.uni_str_len*2 );
|
||||
real_size = unistr.uni_str_len*2;
|
||||
break;
|
||||
|
||||
case REG_MULTI_SZ:
|
||||
string = (char*)val->data_p;
|
||||
real_size = 0;
|
||||
while ( string && *string )
|
||||
{
|
||||
DEBUG(10,("reg_init_buffer2: REG_MULTI_SZ string => [%s], size => [%d]\n", string, real_size ));
|
||||
|
||||
init_unistr2( &unistr, string, strlen(string)+1 );
|
||||
|
||||
list2 = Realloc( list, real_size + unistr.uni_str_len*2 );
|
||||
if ( !list2 )
|
||||
break;
|
||||
list = list2;
|
||||
|
||||
memcpy( list+real_size, unistr.buffer, unistr.uni_str_len*2 );
|
||||
|
||||
real_size += unistr.uni_str_len*2;
|
||||
|
||||
string += strlen(string)+1;
|
||||
}
|
||||
|
||||
list2 = Realloc( list, real_size + 2 );
|
||||
if ( !list2 )
|
||||
break;
|
||||
list = list2;
|
||||
list[real_size++] = 0x0;
|
||||
list[real_size++] = 0x0;
|
||||
|
||||
init_buffer2( buf2, (char*)list, real_size );
|
||||
|
||||
DEBUG(10,("reg_init_buffer2: REG_MULTI_SZ size => [%d]\n", real_size ));
|
||||
|
||||
break;
|
||||
|
||||
case REG_BINARY:
|
||||
DEBUG(10,("reg_init_buffer2: REG_BINARY size => [%d]\n", val->size ));
|
||||
|
||||
init_buffer2( buf2, val->data_p, val->size );
|
||||
break;
|
||||
|
||||
case REG_DWORD:
|
||||
DEBUG(10,("reg_init_buffer2: REG_DWORD value => [%d]\n", *(uint32*)val->data_p));
|
||||
init_buffer2( buf2, val->data_p, val->size );
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG(0,("reg_init_buffer2: Unsupported registry data type [%d]\n", val->type));
|
||||
break;
|
||||
}
|
||||
|
||||
SAFE_FREE( list );
|
||||
|
||||
return real_size;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Inits a structure.
|
||||
********************************************************************/
|
||||
@ -165,6 +249,8 @@ BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
Inits a structure.
|
||||
********************************************************************/
|
||||
@ -583,7 +669,7 @@ BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int d
|
||||
return False;
|
||||
if(!smb_io_time("mod_time ", &r_r->mod_time, ps, depth))
|
||||
return False;
|
||||
|
||||
|
||||
if(!prs_ntstatus("status", ps, depth, &r_r->status))
|
||||
return False;
|
||||
|
||||
@ -599,6 +685,7 @@ void init_reg_q_unknown_1a(REG_Q_UNKNOWN_1A *q_o, POLICY_HND *hnd)
|
||||
memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
reads or writes a structure.
|
||||
********************************************************************/
|
||||
@ -613,7 +700,7 @@ BOOL reg_io_q_unknown_1a(char *desc, REG_Q_UNKNOWN_1A *r_q, prs_struct *ps, int
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
|
||||
if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
|
||||
return False;
|
||||
|
||||
@ -634,7 +721,7 @@ BOOL reg_io_r_unknown_1a(char *desc, REG_R_UNKNOWN_1A *r_r, prs_struct *ps, int
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
|
||||
if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
|
||||
return False;
|
||||
if(!prs_ntstatus("status" , ps, depth, &r_r->status))
|
||||
@ -643,6 +730,57 @@ BOOL reg_io_r_unknown_1a(char *desc, REG_R_UNKNOWN_1A *r_r, prs_struct *ps, int
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
reads or writes a structure.
|
||||
********************************************************************/
|
||||
|
||||
BOOL reg_io_q_save_key(char *desc, REG_Q_SAVE_KEY *r_q, prs_struct *ps, int depth)
|
||||
{
|
||||
if (r_q == NULL)
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "reg_io_q_save_key");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!smb_io_unihdr ("hdr_file", &r_q->hdr_file, ps, depth))
|
||||
return False;
|
||||
if(!smb_io_unistr2("uni_file", &r_q->uni_file, r_q->hdr_file.buffer, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("unknown", ps, depth, &r_q->unknown))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
reads or writes a structure.
|
||||
********************************************************************/
|
||||
|
||||
BOOL reg_io_r_save_key(char *desc, REG_R_SAVE_KEY *r_r, prs_struct *ps, int depth)
|
||||
{
|
||||
if (r_r == NULL)
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "reg_io_r_save_key");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!prs_ntstatus("status" , ps, depth, &r_r->status))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Inits a structure.
|
||||
********************************************************************/
|
||||
@ -1023,6 +1161,51 @@ BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Inits a structure.
|
||||
New version to replace older init_reg_r_info()
|
||||
********************************************************************/
|
||||
|
||||
BOOL new_init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
|
||||
REGISTRY_VALUE *val, NTSTATUS status)
|
||||
{
|
||||
uint32 buf_len = 0;
|
||||
BUFFER2 buf2;
|
||||
|
||||
if(r_r == NULL)
|
||||
return False;
|
||||
|
||||
if ( !val )
|
||||
return False;
|
||||
|
||||
r_r->ptr_type = 1;
|
||||
r_r->type = val->type;
|
||||
|
||||
/* if include_keyval is not set, don't send the key value, just
|
||||
the buflen data. probably used by NT5 to allocate buffer space - SK */
|
||||
|
||||
if ( include_keyval ) {
|
||||
r_r->ptr_uni_val = 1;
|
||||
buf_len = reg_init_buffer2( &r_r->uni_val, val );
|
||||
|
||||
}
|
||||
else {
|
||||
/* dummy buffer used so we can get the size */
|
||||
r_r->ptr_uni_val = 0;
|
||||
buf_len = reg_init_buffer2( &buf2, val );
|
||||
}
|
||||
|
||||
r_r->ptr_max_len = 1;
|
||||
r_r->buf_max_len = buf_len;
|
||||
|
||||
r_r->ptr_len = 1;
|
||||
r_r->buf_len = buf_len;
|
||||
|
||||
r_r->status = status;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Inits a structure.
|
||||
********************************************************************/
|
||||
@ -1030,28 +1213,27 @@ BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth)
|
||||
BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
|
||||
BUFFER2* buf, uint32 type, NTSTATUS status)
|
||||
{
|
||||
if(r_r == NULL)
|
||||
return False;
|
||||
|
||||
if(r_r == NULL)
|
||||
return False;
|
||||
|
||||
r_r->ptr_type = 1;
|
||||
r_r->type = type;
|
||||
r_r->ptr_type = 1;
|
||||
r_r->type = type;
|
||||
|
||||
/* if include_keyval is not set, don't send the key value, just
|
||||
the buflen data. probably used by NT5 to allocate buffer space - SK */
|
||||
r_r->ptr_uni_val = include_keyval ? 1:0;
|
||||
r_r->uni_val = buf;
|
||||
/* if include_keyval is not set, don't send the key value, just
|
||||
the buflen data. probably used by NT5 to allocate buffer space - SK */
|
||||
|
||||
r_r->ptr_max_len = 1;
|
||||
r_r->buf_max_len = r_r->uni_val->buf_max_len;
|
||||
r_r->ptr_uni_val = include_keyval ? 1:0;
|
||||
r_r->uni_val = *buf;
|
||||
|
||||
r_r->ptr_len = 1;
|
||||
r_r->buf_len = r_r->uni_val->buf_len;
|
||||
r_r->ptr_max_len = 1;
|
||||
r_r->buf_max_len = r_r->uni_val.buf_max_len;
|
||||
|
||||
r_r->status = status;
|
||||
r_r->ptr_len = 1;
|
||||
r_r->buf_len = r_r->uni_val.buf_len;
|
||||
|
||||
return True;
|
||||
|
||||
r_r->status = status;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -1081,7 +1263,7 @@ BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
|
||||
return False;
|
||||
|
||||
if(r_r->ptr_uni_val != 0) {
|
||||
if(!smb_io_buffer2("uni_val", r_r->uni_val, r_r->ptr_uni_val, ps, depth))
|
||||
if(!smb_io_buffer2("uni_val", &r_r->uni_val, r_r->ptr_uni_val, ps, depth))
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -1138,6 +1320,46 @@ void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
|
||||
q_i->len_value2 = 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
makes a structure.
|
||||
********************************************************************/
|
||||
|
||||
void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
|
||||
{
|
||||
uint32 real_size;
|
||||
|
||||
DEBUG(8,("init_reg_r_enum_val: Enter\n"));
|
||||
|
||||
ZERO_STRUCTP(r_u);
|
||||
|
||||
/* value name */
|
||||
|
||||
DEBUG(10,("init_reg_r_enum_val: Valuename => [%s]\n", val->valuename));
|
||||
|
||||
init_uni_hdr( &r_u->hdr_name, strlen(val->valuename)+1 );
|
||||
init_unistr2( &r_u->uni_name, val->valuename, strlen(val->valuename)+1 );
|
||||
|
||||
/* type */
|
||||
|
||||
r_u->ptr_type = 1;
|
||||
r_u->type = val->type;
|
||||
|
||||
/* REG_SZ & REG_MULTI_SZ must be converted to UNICODE */
|
||||
|
||||
r_u->ptr_value = 1;
|
||||
real_size = reg_init_buffer2( &r_u->buf_value, val );
|
||||
|
||||
/* lengths */
|
||||
|
||||
r_u->ptr1 = 1;
|
||||
r_u->len_value1 = real_size;
|
||||
|
||||
r_u->ptr2 = 1;
|
||||
r_u->len_value2 = real_size;
|
||||
|
||||
DEBUG(8,("init_reg_r_enum_val: Exit\n"));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
reads or writes a structure.
|
||||
********************************************************************/
|
||||
@ -1158,6 +1380,7 @@ BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int d
|
||||
|
||||
if(!prs_uint32("val_index", ps, depth, &q_q->val_index))
|
||||
return False;
|
||||
|
||||
if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
|
||||
return False;
|
||||
if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
|
||||
@ -1228,7 +1451,7 @@ BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int d
|
||||
|
||||
if(!prs_uint32("ptr_value", ps, depth, &r_q->ptr_value))
|
||||
return False;
|
||||
if(!smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth))
|
||||
if(!smb_io_buffer2("buf_value", &r_q->buf_value, r_q->ptr_value, ps, depth))
|
||||
return False;
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
@ -1531,7 +1754,7 @@ BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int
|
||||
|
||||
if(!prs_uint32("unknown_0 ", ps, depth, &r_q->unknown_0))
|
||||
return False;
|
||||
if(!prs_uint32("asccess_desired ", ps, depth, &r_q->access_desired))
|
||||
if(!prs_uint32("access_desired ", ps, depth, &r_q->access_desired))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user