1
0
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:
Jelmer Vernooij 2002-08-17 17:00:51 +00:00
parent 669a39fae3
commit b2edf254ed
103 changed files with 4060 additions and 1485 deletions

View File

@ -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)

View File

@ -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"));

View File

@ -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

View File

@ -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,6 +232,21 @@ 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;
}

View File

@ -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,

View File

@ -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) {
nt_status = NT_STATUS(response.data.auth.nt_status);
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;
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;

View File

@ -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;
}

View File

@ -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();

View File

@ -282,16 +282,13 @@ 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...
*/

90
source3/configure vendored
View File

@ -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

View File

@ -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

View File

@ -5,18 +5,34 @@
*/
typedef struct {
void *ld;
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;
/* info needed to find the server */
struct {
char *realm;
char *workgroup;
char *ldap_server;
char *ldap_server_name;
char *kdc_server;
int ldap_port;
char *bind_path;
time_t last_attempt;
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 *server_realm;
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

View File

@ -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

View File

@ -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"

View File

@ -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 */

View File

@ -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

View File

@ -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. */

View File

@ -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;

View File

@ -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);

View File

@ -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
{

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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_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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -1 +1 @@
#define VERSION "3.0-alpha17"
#define VERSION "3.0-alpha18"

View File

@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
VFS structures and parameters
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 */

View File

@ -106,8 +106,10 @@ BOOL lang_tdb_init(const char *lang)
if (initialised) {
/* we are re-initialising, free up any old init */
if (tdb) {
tdb_close(tdb);
tdb = NULL;
}
SAFE_FREE(current_lang);
}

View File

@ -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;

View File

@ -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,6 +562,7 @@ int pull_ucs2(const void *base_ptr, char *dest, const void *src, int dest_len, i
}
/* ucs2 is always a multiple of 2 bytes */
if (src_len != -1)
src_len &= ~1;
ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len);
@ -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);
}
/**

View File

@ -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;
}

View File

@ -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';

View File

@ -428,3 +428,5 @@ char *rep_inet_ntoa(struct in_addr ip)
}
#endif /* HAVE_SYSLOG */
#endif /* HAVE_VSYSLOG */

View File

@ -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);

View File

@ -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;

View File

@ -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.
****************************************************************************/

View File

@ -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;

View File

@ -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,17 +503,22 @@ 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__
if (stderr_too) {
close(2);
#endif
}
/* 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++) {
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) {
@ -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 */
}

View File

@ -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.

View File

@ -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);

View File

@ -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) );

View File

@ -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"));

View File

@ -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++;

View File

@ -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;

View File

@ -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);
}

View File

@ -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",

View File

@ -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);

View File

@ -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;
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 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 (!ads->ld) {
return ADS_ERROR_SYSTEM(errno);
/* try via DNS */
if (ads_try_dns(ads)) {
goto got_connection;
}
DEBUG(3,("Connected to LDAP server %s\n", ads->ldap_server));
/* try via netbios lookups */
if (!lp_disable_netbios() && ads_try_netbios(ads)) {
goto got_connection;
}
return ADS_ERROR_SYSTEM(errno?errno:ENOENT);
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

View File

@ -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;

View File

@ -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,

View File

@ -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)) {

View File

@ -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)));

View File

@ -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;

View File

@ -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;
@ -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)) {
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)) {
@ -878,6 +914,10 @@ static BOOL internal_resolve_name(const char *name, int name_type,
*return_count = nodupes_count;
}
/* Save in name cache */
namecache_store(name, name_type, *return_count, *return_iplist);
/* Display some debugging info */
DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
@ -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);
@ -958,10 +1003,14 @@ BOOL lookup_dc_name(const char *srcname, const char *domain,
struct in_addr *dc_ip, char *ret_name)
{
#if !defined(I_HATE_WINDOWS_REPLY_CODE)
fstring dc_name;
BOOL ret;
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
* query here... JRA.

View File

@ -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]);

View File

@ -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)) {

View File

@ -122,6 +122,7 @@ void kill_async_dns_child(void)
{
if (child_pid > 0) {
kill(child_pid, SIGTERM);
child_pid = -1;
}
}

View File

@ -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);
}

View File

@ -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));

View File

@ -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);
}
}
}

View File

@ -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. */

View File

@ -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);

View File

@ -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;
/* 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 += 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;

View File

@ -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,7 +245,7 @@ static char *_pam_delete(register char *xx)
* obtain a password from the user
*/
int _winbind_read_password(pam_handle_t * pamh
static int _winbind_read_password(pam_handle_t * pamh
,unsigned int ctrl
,const char *comment
,const char *prompt1

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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. */

View File

@ -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 */

View File

@ -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

View File

@ -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
};

View File

@ -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));
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);
}
if (!ret) {
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];
goto done;
}
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];
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);
}

View File

@ -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));

View File

@ -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;

View File

@ -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,25 +260,41 @@ 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,
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));

View File

@ -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
};

View File

@ -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));

View File

@ -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));

View File

@ -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;
}

View File

@ -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));

View File

@ -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;

View File

@ -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,6 +189,17 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
-- abartlet 11-May-02
*/
/* 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"));
@ -202,6 +219,7 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
return NT_STATUS_INVALID_PARAMETER;
}
}
}
/* check if this is a user account or a machine account */
if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
@ -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 */
/* yes it's a mapped 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;
}
} 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);
} 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;
}
pdb_free_sam(&sam_user);
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)));
}
*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,26 +905,36 @@ 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;

View File

@ -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,9 +1028,8 @@ 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 {

View File

@ -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);

View File

@ -1,10 +1,11 @@
/*
Unix SMB/CIFS implementation.
LDAP protocol helper functions for SAMBA
Copyright (C) Jean François Micouleau 1998
Copyright (C) Gerald Carter 2001
Copyright (C) Shahms King 2001
Copyright (C) Jean François Micouleau 1998
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
@ -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,6 +160,8 @@ 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;
@ -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 */

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -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)) {
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;
}
if (pass) {
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))

View File

@ -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;
@ -456,6 +500,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
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);
if (idx >= start_idx && idx < start_idx + max_num_domains) {
@ -476,6 +524,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
(*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++;

View File

@ -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++;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -39,98 +39,97 @@ static struct printif *current_printif = &generic_printif;
jobids are assigned when a job starts spooling.
*/
static pid_t local_pid;
/***************************************************************************
Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
bit RPC jobids.... JRA.
***************************************************************************/
/* 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 TDB_CONTEXT *rap_tdb;
static uint16 next_rap_jobid;
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)
uint16 pjobid_to_rap(int snum, uint32 jobid)
{
struct printer_queueid_map *p;
uint16 rap_jobid;
TDB_DATA data, key;
char jinfo[8];
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;
}
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;
}
/****************************************************************************
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;
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;
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);
}
}

View File

@ -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;
}

View File

@ -893,10 +893,12 @@ BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *
return False;
if (UNMARSHALLING(ps)) {
if ( str->buf_len ) {
str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
if (str->buffer == NULL)
if ( str->buffer == NULL )
return False;
}
}
p = (char *)str->buffer;

View File

@ -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.
********************************************************************/
@ -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.
********************************************************************/
@ -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.
********************************************************************/
@ -1033,25 +1216,24 @@ BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
if(r_r == NULL)
return False;
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;
r_r->uni_val = *buf;
r_r->ptr_max_len = 1;
r_r->buf_max_len = r_r->uni_val->buf_max_len;
r_r->buf_max_len = r_r->uni_val.buf_max_len;
r_r->ptr_len = 1;
r_r->buf_len = r_r->uni_val->buf_len;
r_r->buf_len = r_r->uni_val.buf_len;
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;

View File

@ -5,8 +5,10 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
* Copyright (C) Paul Ashton 1997-2000,
* Copyright (C) Elrond 2000,
* Copyright (C) Jeremy Allison 2001
* Copyright (C) Jean François Micouleau 1998-2001.
* Copyright (C) Jeremy Allison 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
@ -5067,7 +5069,7 @@ BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER * r_u,
if(!smb_io_pol_hnd("user_pol", &r_u->user_pol, ps, depth))
return False;
if(!prs_uint32("unknown_0", ps, depth, &r_u->unknown_0))
if(!prs_uint32("access_granted", ps, depth, &r_u->access_granted))
return False;
if(!prs_uint32("user_rid ", ps, depth, &r_u->user_rid))
return False;
@ -5945,7 +5947,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
const char* user_name = pdb_get_username(pw);
const char* full_name = pdb_get_fullname(pw);
const char* home_dir = pdb_get_homedir(pw);
const char* dir_drive = pdb_get_dirdrive(pw);
const char* dir_drive = pdb_get_dir_drive(pw);
const char* logon_script = pdb_get_logon_script(pw);
const char* profile_path = pdb_get_profile_path(pw);
const char* description = pdb_get_acct_desc(pw);
@ -6716,6 +6718,84 @@ BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT * r_u,
return True;
}
/*******************************************************************
inits a SAMR_Q_CONNECT4 structure.
********************************************************************/
void init_samr_q_connect4(SAMR_Q_CONNECT4 * q_u,
char *srv_name, uint32 access_mask)
{
int len_srv_name = strlen(srv_name);
DEBUG(5, ("init_samr_q_connect\n"));
/* make PDC server name \\server */
q_u->ptr_srv_name = len_srv_name > 0 ? 1 : 0;
init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name + 1);
/* Only value we've seen, possibly an address type ? */
q_u->unk_0 = 2;
/* example values: 0x0000 0002 */
q_u->access_mask = access_mask;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
BOOL samr_io_q_connect4(char *desc, SAMR_Q_CONNECT4 * q_u,
prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
prs_debug(ps, depth, desc, "samr_io_q_connect4");
depth++;
if(!prs_align(ps))
return False;
if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
return False;
if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
return False;
if(!prs_align(ps))
return False;
if(!prs_uint32("unk_0", ps, depth, &q_u->unk_0))
return False;
if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
return False;
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
BOOL samr_io_r_connect4(char *desc, SAMR_R_CONNECT4 * r_u,
prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
prs_debug(ps, depth, desc, "samr_io_r_connect4");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
return False;
if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
inits a SAMR_Q_CONNECT_ANON structure.
********************************************************************/

Some files were not shown because too many files have changed in this diff Show More