1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-14 20:23:54 +03:00
Files
samba-mirror/source/lib/sids.c
Luke Leighton 97ec74e1fa modified domain_client_validate to take trust account name / type. this
is to pass DOMAIN_NAME$ and SEC_CHAN_DOMAIN instead of WKSTA_NAME$ and
SEC_CHAN_WKSTA.

modified check_domain_security to determine if domain name is own domain,
and to use wksta trust account if so, otherwise check "trusting domains"
parameter and use inter-domain trust account if so, otherwise return
False.
-

403 lines
9.8 KiB
C

/*
Unix SMB/Netbios implementation.
Version 1.9.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
extern int DEBUGLEVEL;
extern pstring scope;
extern pstring global_myname;
/*
* This is set on startup - it defines the SID for this
* machine, and therefore the SAM database for which it is
* responsible.
*/
DOM_SID global_sam_sid;
/*
* This is the name associated with the SAM database for
* which this machine is responsible. In the case of a PDC
* or PDC, this name is the same as the workgroup. In the
* case of "security = domain" mode, this is the same as
* the name of the server (global_myname).
*/
fstring global_sam_name;
/*
* This is obtained on startup - it defines the SID for which
* this machine is a member. It is therefore only set, and
* used, in "security = domain" mode.
*/
DOM_SID global_member_sid;
/*
* note the lack of a "global_member_name" - this is because
* this is the same as "global_myworkgroup".
*/
extern fstring global_myworkgroup;
/* fstring global_member_dom_name; */
/*
* some useful sids
*/
DOM_SID global_sid_S_1_5_20; /* local well-known domain */
DOM_SID global_sid_S_1_1; /* everyone */
DOM_SID global_sid_S_1_3; /* Creator Owner */
DOM_SID global_sid_S_1_5; /* NT Authority */
static struct sid_name_map_info
{
DOM_SID *sid;
char *name;
}
sid_name_map[] =
{
{ &global_sid_S_1_5_20, "BUILTIN" },
{ &global_sid_S_1_1 , "Everyone" },
{ &global_sid_S_1_3 , "Creator Owner" },
{ &global_sid_S_1_5 , "NT Authority" },
{ &global_sam_sid , global_sam_name },
{ &global_member_sid , global_myworkgroup },
{ NULL , NULL }
};
/****************************************************************************
sets up the name associated with the SAM database for which we are responsible
****************************************************************************/
void get_sam_domain_name(void)
{
switch (lp_server_role())
{
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
{
/* we are PDC (or BDC) for a Domain */
fstrcpy(global_sam_name, lp_workgroup());
break;
}
case ROLE_DOMAIN_MEMBER:
{
/* we are a "PDC", but FOR LOCAL SAM DATABASE ONLY */
fstrcpy(global_sam_name, global_myname);
break;
}
default:
{
/* no domain role, probably due to "security = share" */
memset(global_sam_name, 0, sizeof(global_sam_name));
break;
}
}
}
/****************************************************************************
obtain the sid from the PDC.
****************************************************************************/
BOOL get_member_domain_sid(void)
{
switch (lp_server_role())
{
case ROLE_DOMAIN_NONE:
{
ZERO_STRUCT(global_member_sid);
return True;
}
case ROLE_DOMAIN_PDC:
{
sid_copy(&global_member_sid, &global_sam_sid);
return True;
}
default:
{
/* member or BDC, we're going for connection to PDC */
break;
}
}
return get_domain_sids(global_myname, NULL,
&global_member_sid, lp_passwordserver());
}
/****************************************************************************
creates some useful well known sids
****************************************************************************/
void generate_wellknown_sids(void)
{
string_to_sid(&global_sid_S_1_5_20, "S-1-5-32");
string_to_sid(&global_sid_S_1_1 , "S-1-1" );
string_to_sid(&global_sid_S_1_3 , "S-1-3" );
string_to_sid(&global_sid_S_1_5 , "S-1-5" );
}
/****************************************************************************
Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
****************************************************************************/
BOOL generate_sam_sid(char *domain_name, DOM_SID *sid)
{
char *p;
pstring sid_file;
pstring machine_sid_file;
fstring file_name;
pstrcpy(sid_file, lp_smb_passwd_file());
if (sid_file[0] == 0)
{
DEBUG(0,("cannot find smb passwd file\n"));
return False;
}
p = strrchr(sid_file, '/');
if (p != NULL)
{
*++p = '\0';
}
if (!directory_exist(sid_file, NULL)) {
if (mkdir(sid_file, 0700) != 0) {
DEBUG(0,("can't create private directory %s : %s\n",
sid_file, strerror(errno)));
return False;
}
}
pstrcpy(machine_sid_file, sid_file);
pstrcat(machine_sid_file, "MACHINE.SID");
slprintf(file_name, sizeof(file_name)-1, "%s.SID", domain_name);
strupper(file_name);
pstrcat(sid_file, file_name);
if (file_exist(machine_sid_file, NULL))
{
if (file_exist(sid_file, NULL))
{
DEBUG(0,("both %s and %s exist when only one should, unable to continue\n",
machine_sid_file, sid_file));
return False;
}
if (file_rename(machine_sid_file, sid_file))
{
DEBUG(0,("could not rename %s to %s. Error was %s\n",
machine_sid_file, sid_file, strerror(errno)));
return False;
}
}
/* attempt to read the SID from the file */
if (read_sid(domain_name, sid))
{
return True;
}
if (!create_new_sid(sid))
{
return False;
}
/* attempt to read the SID from the file */
if (!write_sid(domain_name, sid))
{
return True;
}
/* during the attempt to write, someone else wrote? */
/* attempt to read the SID from the file */
if (read_sid(domain_name, sid))
{
return True;
}
return True;
}
/**************************************************************************
turns a domain name into a SID.
*** side-effect: if the domain name is NULL, it is set to our domain ***
***************************************************************************/
BOOL map_domain_name_to_sid(DOM_SID *sid, char **nt_domain)
{
int i = 0;
if (nt_domain == NULL)
{
sid_copy(sid, &global_sam_sid);
return True;
}
if ((*nt_domain) == NULL)
{
DEBUG(5,("map_domain_name_to_sid: overriding NULL name to %s\n",
global_sam_name));
(*nt_domain) = strdup(global_sam_name);
sid_copy(sid, &global_sam_sid);
return True;
}
if ((*nt_domain)[0] == 0)
{
free(*nt_domain);
(*nt_domain) = strdup(global_sam_name);
DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n",
(*nt_domain)));
sid_copy(sid, &global_sam_sid);
return True;
}
DEBUG(5,("map_domain_name_to_sid: %s\n", (*nt_domain)));
while (sid_name_map[i].name != NULL)
{
DEBUG(5,("compare: %s\n", sid_name_map[i].name));
if (strequal(sid_name_map[i].name, (*nt_domain)))
{
fstring sid_str;
sid_copy(sid, sid_name_map[i].sid);
sid_to_string(sid_str, sid_name_map[i].sid);
DEBUG(5,("found %s\n", sid_str));
return True;
}
i++;
}
DEBUG(0,("map_domain_name_to_sid: mapping to %s NOT IMPLEMENTED\n",
(*nt_domain)));
return False;
}
/**************************************************************************
turns a domain SID into a name.
***************************************************************************/
BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain)
{
fstring sid_str;
int i = 0;
sid_to_string(sid_str, sid);
DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
if (nt_domain == NULL)
{
return False;
}
while (sid_name_map[i].sid != NULL)
{
sid_to_string(sid_str, sid_name_map[i].sid);
DEBUG(5,("compare: %s\n", sid_str));
if (sid_equal(sid_name_map[i].sid, sid))
{
fstrcpy(nt_domain, sid_name_map[i].name);
DEBUG(5,("found %s\n", nt_domain));
return True;
}
i++;
}
DEBUG(0,("map_domain_sid_to_name: mapping NOT IMPLEMENTED\n"));
return False;
}
/**************************************************************************
splits a name of format \DOMAIN\name or name into its two components.
sets the DOMAIN name to global_sam_name if it has not been specified.
***************************************************************************/
BOOL split_domain_name(const char *fullname, char *domain, char *name)
{
fstring full_name;
char *p;
if (fullname == NULL || domain == NULL || name == NULL)
{
return False;
}
if (fullname[0] == '\\')
{
fullname++;
}
fstrcpy(full_name, fullname);
p = strchr(full_name+1, '\\');
if (p != NULL)
{
*p = 0;
fstrcpy(domain, full_name);
fstrcpy(name, p+1);
}
else
{
fstrcpy(domain, global_sam_name);
fstrcpy(name, full_name);
}
DEBUG(10,("name '%s' split into domain:%s and nt name:%s'\n", fullname, domain, name));
return True;
}
/**************************************************************************
enumerates all domains for which the SAM server is responsible
***************************************************************************/
BOOL enumtrustdoms(char ***doms, uint32 *num_entries)
{
fstring tmp;
char *tok;
/* add trusted domains */
tok = lp_trusted_domains();
if (next_token(&tok, tmp, NULL, sizeof(tmp)))
{
do
{
add_chars_to_array(num_entries, doms, tmp);
} while (next_token(NULL, tmp, NULL, sizeof(tmp)));
}
return True;
}
/**************************************************************************
enumerates all domains for which the SAM server is responsible
***************************************************************************/
BOOL enumdomains(char ***doms, uint32 *num_entries)
{
add_chars_to_array(num_entries, doms, global_sam_name);
add_chars_to_array(num_entries, doms, "Builtin");
return True;
}