mirror of
https://github.com/samba-team/samba.git
synced 2025-11-30 20:23:49 +03:00
r12051: Merge across the lookup_name and lookup_sid work. Lets see how the build farm
reacts :-) Volker
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
b9d1a65910
commit
9f99d04a54
@@ -326,7 +326,7 @@ LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
|
||||
PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o
|
||||
|
||||
PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
|
||||
passdb/util_sam_sid.o passdb/pdb_compat.o \
|
||||
passdb/util_wellknown.o passdb/util_builtin.o passdb/pdb_compat.o \
|
||||
passdb/lookup_sid.o \
|
||||
passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o \
|
||||
lib/system_smbd.o lib/account_pol.o lib/privileges.o
|
||||
|
||||
@@ -1550,7 +1550,7 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
|
||||
Check for a SID in an NT_USER_TOKEN
|
||||
****************************************************************************/
|
||||
|
||||
BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
|
||||
static BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1598,8 +1598,6 @@ BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
|
||||
BOOL is_trusted_domain(const char* dom_name)
|
||||
{
|
||||
DOM_SID trustdom_sid;
|
||||
char *pass = NULL;
|
||||
time_t lct;
|
||||
BOOL ret;
|
||||
|
||||
/* no trusted domains for a standalone server */
|
||||
@@ -1613,9 +1611,8 @@ BOOL is_trusted_domain(const char* dom_name)
|
||||
become_root();
|
||||
DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",
|
||||
dom_name ));
|
||||
ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
|
||||
ret = secrets_fetch_trusted_domain_password(dom_name, NULL, NULL, NULL);
|
||||
unbecome_root();
|
||||
SAFE_FREE(pass);
|
||||
if (ret)
|
||||
return True;
|
||||
}
|
||||
|
||||
@@ -1166,11 +1166,22 @@ NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
|
||||
enum SID_NAME_USE type;
|
||||
uint32 new_rid;
|
||||
gid_t gid;
|
||||
|
||||
BOOL exists;
|
||||
GROUP_MAP map;
|
||||
|
||||
if (lookup_name(get_global_sam_name(), name, &sid, &type))
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
|
||||
if (mem_ctx == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
exists = lookup_name(mem_ctx, name, LOOKUP_NAME_ISOLATED,
|
||||
NULL, NULL, &sid, &type);
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
if (exists) {
|
||||
return NT_STATUS_ALIAS_EXISTS;
|
||||
}
|
||||
|
||||
if (!winbind_allocate_rid_and_gid(&new_rid, &gid))
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
|
||||
@@ -376,6 +376,13 @@ typedef struct pdb_context
|
||||
const char **pp_names,
|
||||
uint32 *attrs);
|
||||
|
||||
NTSTATUS (*pdb_lookup_names)(struct pdb_context *context,
|
||||
const DOM_SID *domain_sid,
|
||||
size_t num_names,
|
||||
const char **names,
|
||||
uint32 *rids,
|
||||
uint32 *attrs);
|
||||
|
||||
NTSTATUS (*pdb_get_account_policy)(struct pdb_context *context,
|
||||
int policy_index, uint32 *value);
|
||||
|
||||
@@ -499,6 +506,13 @@ typedef struct pdb_methods
|
||||
const char **pp_names,
|
||||
uint32 *attrs);
|
||||
|
||||
NTSTATUS (*lookup_names)(struct pdb_methods *methods,
|
||||
const DOM_SID *domain_sid,
|
||||
int num_names,
|
||||
const char **pp_names,
|
||||
uint32 *rids,
|
||||
uint32 *attrs);
|
||||
|
||||
NTSTATUS (*get_account_policy)(struct pdb_methods *methods,
|
||||
int policy_index, uint32 *value);
|
||||
|
||||
|
||||
@@ -264,6 +264,10 @@ enum SID_NAME_USE
|
||||
SID_NAME_COMPUTER /* sid for a computer */
|
||||
};
|
||||
|
||||
#define LOOKUP_NAME_ISOLATED 1 /* Look up unqualified names */
|
||||
#define LOOKUP_NAME_REMOTE 2 /* Ask others */
|
||||
#define LOOKUP_NAME_ALL (LOOKUP_NAME_ISOLATED|LOOKUP_NAME_REMOTE)
|
||||
|
||||
/**
|
||||
* @brief Security Identifier
|
||||
*
|
||||
|
||||
@@ -75,11 +75,14 @@ const DOM_SID global_sid_Builtin_Backup_Operators = /* Builtin backup operators
|
||||
const DOM_SID global_sid_Builtin_Replicator = /* Builtin replicator */
|
||||
{ 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
|
||||
|
||||
/* Unused, left here for documentary purposes */
|
||||
#if 0
|
||||
#define SECURITY_NULL_SID_AUTHORITY 0
|
||||
#define SECURITY_WORLD_SID_AUTHORITY 1
|
||||
#define SECURITY_LOCAL_SID_AUTHORITY 2
|
||||
#define SECURITY_CREATOR_SID_AUTHORITY 3
|
||||
#define SECURITY_NT_AUTHORITY 5
|
||||
#endif
|
||||
|
||||
/*
|
||||
* An NT compatible anonymous token.
|
||||
@@ -188,24 +191,6 @@ void split_domain_name(const char *fullname, char *domain, char *name)
|
||||
fullname, domain, name));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Test if a SID is wellknown and resolvable.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL resolvable_wellknown_sid(DOM_SID *sid)
|
||||
{
|
||||
uint32 ia = (sid->id_auth[5]) +
|
||||
(sid->id_auth[4] << 8 ) +
|
||||
(sid->id_auth[3] << 16) +
|
||||
(sid->id_auth[2] << 24);
|
||||
|
||||
if (sid->sid_rev_num != SEC_DESC_REVISION || sid->num_auths < 1)
|
||||
return False;
|
||||
|
||||
return (ia == SECURITY_WORLD_SID_AUTHORITY ||
|
||||
ia == SECURITY_CREATOR_SID_AUTHORITY);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Convert a SID to an ascii string.
|
||||
*****************************************************************/
|
||||
@@ -532,30 +517,6 @@ BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
|
||||
return sid_compare(sid1, sid2) == 0;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Check if the SID is the builtin SID (S-1-5-32).
|
||||
*****************************************************************/
|
||||
|
||||
BOOL sid_check_is_builtin(const DOM_SID *sid)
|
||||
{
|
||||
return sid_equal(sid, &global_sid_Builtin);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Check if the SID is one of the builtin SIDs (S-1-5-32-a).
|
||||
*****************************************************************/
|
||||
|
||||
BOOL sid_check_is_in_builtin(const DOM_SID *sid)
|
||||
{
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
|
||||
sid_copy(&dom_sid, sid);
|
||||
sid_split_rid(&dom_sid, &rid);
|
||||
|
||||
return sid_equal(&dom_sid, &global_sid_Builtin);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Calculates size of a sid.
|
||||
*****************************************************************/
|
||||
|
||||
@@ -105,27 +105,6 @@ static struct afs_ace *clone_afs_ace(TALLOC_CTX *mem_ctx, struct afs_ace *ace)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Ok, this is sort-of a hack. We assume here that we have winbind users in
|
||||
* AFS. And yet another copy of parse_domain_user.... */
|
||||
|
||||
static BOOL parse_domain_user(const char *domuser, fstring domain,
|
||||
fstring user)
|
||||
{
|
||||
char *p = strchr(domuser,*lp_winbind_separator());
|
||||
|
||||
if (p==NULL) {
|
||||
return False;
|
||||
}
|
||||
|
||||
fstrcpy(user, p+1);
|
||||
fstrcpy(domain, domuser);
|
||||
domain[PTR_DIFF(p, domuser)] = 0;
|
||||
strupper_m(domain);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static struct afs_ace *new_afs_ace(TALLOC_CTX *mem_ctx,
|
||||
BOOL positive,
|
||||
const char *name, uint32 rights)
|
||||
@@ -168,14 +147,16 @@ static struct afs_ace *new_afs_ace(TALLOC_CTX *mem_ctx,
|
||||
|
||||
} else {
|
||||
|
||||
fstring user, domain;
|
||||
fstring domain, uname;
|
||||
char *p;
|
||||
|
||||
if (!parse_domain_user(name, domain, user)) {
|
||||
fstrcpy(user, name);
|
||||
fstrcpy(domain, lp_workgroup());
|
||||
p = strchr_m(name, lp_winbind_separator());
|
||||
if (p != NULL) {
|
||||
*p = '\\';
|
||||
}
|
||||
|
||||
if (!lookup_name(domain, user, &sid, &type)) {
|
||||
if (!lookup_name(name, LOOKUP_NAME_FULL,
|
||||
domain, uname, &sid, &type)) {
|
||||
DEBUG(10, ("Could not find AFS user %s\n", name));
|
||||
|
||||
sid_copy(&sid, &global_sid_NULL);
|
||||
|
||||
@@ -64,39 +64,52 @@ 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(const DOM_SID *sid,
|
||||
fstring dom_name, fstring name,
|
||||
BOOL winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
|
||||
char **domain, char **name,
|
||||
enum SID_NAME_USE *name_type)
|
||||
{
|
||||
struct winbindd_request request;
|
||||
struct winbindd_response response;
|
||||
NSS_STATUS result;
|
||||
fstring sid_str;
|
||||
|
||||
/* Initialise request */
|
||||
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
sid_to_string(sid_str, sid);
|
||||
fstrcpy(request.data.sid, sid_str);
|
||||
fstrcpy(request.data.sid, sid_string_static(sid));
|
||||
|
||||
/* Make request */
|
||||
|
||||
result = winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response);
|
||||
result = winbindd_request_response(WINBINDD_LOOKUPSID, &request,
|
||||
&response);
|
||||
|
||||
if (result != NSS_STATUS_SUCCESS) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Copy out result */
|
||||
|
||||
if (result == NSS_STATUS_SUCCESS) {
|
||||
fstrcpy(dom_name, response.data.name.dom_name);
|
||||
fstrcpy(name, response.data.name.name);
|
||||
if (domain != NULL) {
|
||||
*domain = talloc_strdup(mem_ctx, response.data.name.dom_name);
|
||||
if (*domain == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
if (name != NULL) {
|
||||
*name = talloc_strdup(mem_ctx, response.data.name.name);
|
||||
if (*name == NULL) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
*name_type = (enum SID_NAME_USE)response.data.name.type;
|
||||
|
||||
DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
|
||||
sid_str, dom_name, name));
|
||||
}
|
||||
|
||||
return (result == NSS_STATUS_SUCCESS);
|
||||
sid_string_static(sid), *domain, *name));
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Call winbindd to convert SID to uid */
|
||||
|
||||
@@ -22,43 +22,247 @@
|
||||
#include "includes.h"
|
||||
|
||||
/*****************************************************************
|
||||
*THE CANONICAL* convert name to SID function.
|
||||
Tries local lookup first - for local domains - then uses winbind.
|
||||
Dissect a user-provided name into domain, name, sid and type.
|
||||
|
||||
If an explicit domain name was given in the form domain\user, it
|
||||
has to try that. If no explicit domain name was given, we have
|
||||
to do guesswork.
|
||||
*****************************************************************/
|
||||
|
||||
BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
||||
BOOL lookup_name(TALLOC_CTX *mem_ctx,
|
||||
const char *full_name, int flags,
|
||||
char **ret_domain, char **ret_name,
|
||||
DOM_SID *ret_sid, enum SID_NAME_USE *ret_type)
|
||||
{
|
||||
fstring sid;
|
||||
BOOL local_lookup = False;
|
||||
char *p, *tmp;
|
||||
char *domain = NULL;
|
||||
char *name = NULL;
|
||||
uint32 rid;
|
||||
DOM_SID sid;
|
||||
enum SID_NAME_USE type;
|
||||
|
||||
*name_type = SID_NAME_UNKNOWN;
|
||||
p = strchr_m(full_name, '\\');
|
||||
|
||||
/* If we are looking up a domain user, make sure it is
|
||||
for the local machine only */
|
||||
if (p != NULL) {
|
||||
domain = talloc_strndup(mem_ctx, full_name,
|
||||
PTR_DIFF(p, full_name));
|
||||
name = talloc_strdup(mem_ctx, p+1);
|
||||
} else {
|
||||
domain = talloc_strdup(mem_ctx, "");
|
||||
name = talloc_strdup(mem_ctx, full_name);
|
||||
}
|
||||
|
||||
if ((domain == NULL) || (name == NULL)) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (strequal(domain, get_global_sam_name())) {
|
||||
if (local_lookup_name(name, psid, name_type)) {
|
||||
DEBUG(10,
|
||||
("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n",
|
||||
domain, name, sid_to_string(sid,psid),
|
||||
sid_type_lookup(*name_type), (unsigned int)*name_type));
|
||||
return True;
|
||||
}
|
||||
} else {
|
||||
/* Remote */
|
||||
if (winbind_lookup_name(domain, name, psid, name_type)) {
|
||||
|
||||
DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n",
|
||||
domain, name, sid_to_string(sid, psid),
|
||||
(unsigned int)*name_type));
|
||||
return True;
|
||||
/* It's our own domain, lookup the name in passdb */
|
||||
if (lookup_global_sam_name(name, &rid, &type)) {
|
||||
sid_copy(&sid, get_global_sam_sid());
|
||||
sid_append_rid(&sid, rid);
|
||||
goto ok;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
if (strequal(domain, builtin_domain_name())) {
|
||||
|
||||
/* Explicit request for a name in BUILTIN */
|
||||
if (lookup_builtin_name(name, &rid)) {
|
||||
sid_copy(&sid, &global_sid_Builtin);
|
||||
sid_append_rid(&sid, rid);
|
||||
type = SID_NAME_ALIAS;
|
||||
goto ok;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
if (domain[0] != '\0') {
|
||||
/* An explicit domain name was given, here our last resort is
|
||||
* winbind. */
|
||||
if (winbind_lookup_name(domain, name, &sid, &type)) {
|
||||
goto ok;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!(flags & LOOKUP_NAME_ISOLATED)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Now the guesswork begins, we haven't been given an explicit
|
||||
* domain. Try the sequence as documented on
|
||||
* http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
|
||||
* November 27, 2005 */
|
||||
|
||||
/* 1. well-known names */
|
||||
|
||||
{
|
||||
tmp = domain;
|
||||
if (lookup_wellknown_name(mem_ctx, name, &sid, &domain)) {
|
||||
talloc_free(tmp);
|
||||
type = SID_NAME_WKN_GRP;
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n",
|
||||
local_lookup ? "local" : "winbind", domain, name));
|
||||
/* 2. Builtin domain as such */
|
||||
|
||||
if (strequal(name, builtin_domain_name())) {
|
||||
/* Swap domain and name */
|
||||
tmp = name; name = domain; domain = tmp;
|
||||
sid_copy(&sid, &global_sid_Builtin);
|
||||
type = SID_NAME_DOMAIN;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* 3. Account domain */
|
||||
|
||||
if (strequal(name, get_global_sam_name())) {
|
||||
if (!secrets_fetch_domain_sid(name, &sid)) {
|
||||
DEBUG(3, ("Could not fetch my SID\n"));
|
||||
return False;
|
||||
}
|
||||
/* Swap domain and name */
|
||||
tmp = name; name = domain; domain = tmp;
|
||||
type = SID_NAME_DOMAIN;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* 4. Primary domain */
|
||||
|
||||
if (!IS_DC && strequal(name, lp_workgroup())) {
|
||||
if (!secrets_fetch_domain_sid(name, &sid)) {
|
||||
DEBUG(3, ("Could not fetch the domain SID\n"));
|
||||
return False;
|
||||
}
|
||||
/* Swap domain and name */
|
||||
tmp = name; name = domain; domain = tmp;
|
||||
type = SID_NAME_DOMAIN;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* 5. Trusted domains as such, to me it looks as if members don't do
|
||||
this, tested an XP workstation in a NT domain -- vl */
|
||||
|
||||
if (IS_DC && (secrets_fetch_trusted_domain_password(name, NULL,
|
||||
&sid, NULL))) {
|
||||
/* Swap domain and name */
|
||||
tmp = name; name = domain; domain = tmp;
|
||||
type = SID_NAME_DOMAIN;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* 6. Builtin aliases */
|
||||
|
||||
if (lookup_builtin_name(name, &rid)) {
|
||||
domain = talloc_strdup(mem_ctx, builtin_domain_name());
|
||||
sid_copy(&sid, &global_sid_Builtin);
|
||||
sid_append_rid(&sid, rid);
|
||||
type = SID_NAME_ALIAS;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* 7. Local systems' SAM (DCs don't have a local SAM) */
|
||||
/* 8. Primary SAM (On members, this is the domain) */
|
||||
|
||||
/* Both cases are done by looking at our passdb */
|
||||
|
||||
if (lookup_global_sam_name(name, &rid, &type)) {
|
||||
domain = talloc_strdup(mem_ctx, get_global_sam_name());
|
||||
sid_copy(&sid, get_global_sam_sid());
|
||||
sid_append_rid(&sid, rid);
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* Now our local possibilities are exhausted. */
|
||||
|
||||
if (!(flags & LOOKUP_NAME_REMOTE)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/* If we are not a DC, we have to ask in our primary domain. Let
|
||||
* winbind do that. */
|
||||
|
||||
if (!IS_DC &&
|
||||
(winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
|
||||
domain = talloc_strdup(mem_ctx, lp_workgroup());
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* 9. Trusted domains */
|
||||
|
||||
/* If we're a DC we have to ask all trusted DC's. Winbind does not do
|
||||
* that (yet), but give it a chance. */
|
||||
|
||||
if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
|
||||
DOM_SID dom_sid;
|
||||
uint32 tmp_rid;
|
||||
enum SID_NAME_USE domain_type;
|
||||
|
||||
if (type == SID_NAME_DOMAIN) {
|
||||
/* Swap name and type */
|
||||
tmp = name; name = domain; domain = tmp;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
talloc_free(domain);
|
||||
|
||||
/* Here we have to cope with a little deficiency in the
|
||||
* winbind API: We have to ask it again for the name of the
|
||||
* domain it figured out itself. Maybe fix that later... */
|
||||
|
||||
sid_copy(&dom_sid, &sid);
|
||||
sid_split_rid(&dom_sid, &tmp_rid);
|
||||
|
||||
if (!winbind_lookup_sid(mem_ctx, &dom_sid, &domain, NULL,
|
||||
&domain_type) ||
|
||||
(domain_type != SID_NAME_DOMAIN)) {
|
||||
DEBUG(2, ("winbind could not find the domain's name it "
|
||||
"just looked up for us\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
talloc_free(domain);
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* 10. Don't translate */
|
||||
|
||||
return False;
|
||||
|
||||
ok:
|
||||
if ((domain == NULL) || (name == NULL)) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
strupper_m(domain);
|
||||
|
||||
if (ret_name != NULL) {
|
||||
*ret_name = name;
|
||||
} else {
|
||||
talloc_free(name);
|
||||
}
|
||||
|
||||
if (ret_domain != NULL) {
|
||||
*ret_domain = domain;
|
||||
} else {
|
||||
talloc_free(domain);
|
||||
}
|
||||
|
||||
if (ret_sid != NULL) {
|
||||
sid_copy(ret_sid, &sid);
|
||||
}
|
||||
|
||||
if (ret_type != NULL) {
|
||||
*ret_type = type;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
@@ -66,22 +270,21 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N
|
||||
Tries local lookup first - for local sids, then tries winbind.
|
||||
*****************************************************************/
|
||||
|
||||
BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name,
|
||||
enum SID_NAME_USE *name_type)
|
||||
BOOL lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
|
||||
char **ret_domain, char **ret_name,
|
||||
enum SID_NAME_USE *ret_type)
|
||||
{
|
||||
if (!name_type)
|
||||
return False;
|
||||
|
||||
*name_type = SID_NAME_UNKNOWN;
|
||||
|
||||
char *domain = NULL;
|
||||
char *name = NULL;
|
||||
enum SID_NAME_USE type;
|
||||
/* Check if this is our own sid. This should perhaps be done by
|
||||
winbind? For the moment handle it here. */
|
||||
|
||||
if (sid_check_is_domain(sid)) {
|
||||
fstrcpy(dom_name, get_global_sam_name());
|
||||
fstrcpy(name, "");
|
||||
*name_type = SID_NAME_DOMAIN;
|
||||
return True;
|
||||
domain = talloc_strdup(mem_ctx, get_global_sam_name());
|
||||
name = talloc_strdup(mem_ctx, "");
|
||||
type = SID_NAME_DOMAIN;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (sid_check_is_in_our_domain(sid)) {
|
||||
@@ -89,22 +292,22 @@ BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name,
|
||||
SMB_ASSERT(sid_peek_rid(sid, &rid));
|
||||
|
||||
/* For our own domain passdb is responsible */
|
||||
fstrcpy(dom_name, get_global_sam_name());
|
||||
return lookup_global_sam_rid(rid, name, name_type);
|
||||
if (!lookup_global_sam_rid(mem_ctx, rid, &name, &type)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
domain = talloc_strdup(mem_ctx, get_global_sam_name());
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (sid_check_is_builtin(sid)) {
|
||||
|
||||
/* Got through map_domain_sid_to_name here so that the mapping
|
||||
* of S-1-5-32 to the name "BUILTIN" in as few places as
|
||||
* possible. We might add i18n... */
|
||||
SMB_ASSERT(map_domain_sid_to_name(sid, dom_name));
|
||||
domain = talloc_strdup(mem_ctx, builtin_domain_name());
|
||||
|
||||
/* Yes, W2k3 returns "BUILTIN" both as domain and name here */
|
||||
fstrcpy(name, dom_name);
|
||||
|
||||
*name_type = SID_NAME_DOMAIN;
|
||||
return True;
|
||||
name = talloc_strdup(mem_ctx, builtin_domain_name());
|
||||
type = SID_NAME_DOMAIN;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (sid_check_is_in_builtin(sid)) {
|
||||
@@ -112,39 +315,56 @@ BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name,
|
||||
|
||||
SMB_ASSERT(sid_peek_rid(sid, &rid));
|
||||
|
||||
/* Got through map_domain_sid_to_name here so that the mapping
|
||||
* of S-1-5-32 to the name "BUILTIN" in as few places as
|
||||
* possible. We might add i18n... */
|
||||
SMB_ASSERT(map_domain_sid_to_name(&global_sid_Builtin,
|
||||
dom_name));
|
||||
|
||||
/* There's only aliases in S-1-5-32 */
|
||||
*name_type = SID_NAME_ALIAS;
|
||||
|
||||
return lookup_builtin_rid(rid, name);
|
||||
if (!lookup_builtin_rid(mem_ctx, rid, &name)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if (winbind_lookup_sid(sid, dom_name, name, name_type)) {
|
||||
return True;
|
||||
/* There's only aliases in S-1-5-32 */
|
||||
type = SID_NAME_ALIAS;
|
||||
domain = talloc_strdup(mem_ctx, builtin_domain_name());
|
||||
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (winbind_lookup_sid(mem_ctx, sid, &domain, &name, &type)) {
|
||||
goto ok;
|
||||
}
|
||||
|
||||
DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying "
|
||||
"special SIDs.\n", sid_string_static(sid)));
|
||||
|
||||
{
|
||||
const char *dom, *obj_name;
|
||||
|
||||
if (lookup_special_sid(sid, &dom, &obj_name, name_type)) {
|
||||
DEBUG(10, ("found %s\\%s\n", dom, obj_name));
|
||||
fstrcpy(dom_name, dom);
|
||||
fstrcpy(name, obj_name);
|
||||
return True;
|
||||
}
|
||||
if (lookup_wellknown_sid(mem_ctx, sid, &domain, &name)) {
|
||||
type = SID_NAME_WKN_GRP;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
DEBUG(10, ("lookup_sid failed\n"));
|
||||
|
||||
DEBUG(10, ("Failed to lookup sid %s\n", sid_string_static(sid)));
|
||||
return False;
|
||||
|
||||
ok:
|
||||
|
||||
if ((domain == NULL) || (name == NULL)) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (ret_domain != NULL) {
|
||||
*ret_domain = domain;
|
||||
} else {
|
||||
talloc_free(domain);
|
||||
}
|
||||
|
||||
if (ret_name != NULL) {
|
||||
*ret_name = name;
|
||||
} else {
|
||||
talloc_free(name);
|
||||
}
|
||||
|
||||
if (ret_type != NULL) {
|
||||
*ret_type = type;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
@@ -187,10 +407,9 @@ static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
|
||||
|
||||
for (pc = uid_sid_cache_head; pc; pc = pc->next) {
|
||||
if (pc->uid == uid) {
|
||||
fstring sid;
|
||||
*psid = pc->sid;
|
||||
DEBUG(3,("fetch sid from uid cache %u -> %s\n",
|
||||
(unsigned int)uid, sid_to_string(sid, psid)));
|
||||
(unsigned int)uid, sid_string_static(psid)));
|
||||
DLIST_PROMOTE(uid_sid_cache_head, pc);
|
||||
return True;
|
||||
}
|
||||
@@ -208,10 +427,9 @@ static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
|
||||
|
||||
for (pc = uid_sid_cache_head; pc; pc = pc->next) {
|
||||
if (sid_compare(&pc->sid, psid) == 0) {
|
||||
fstring sid;
|
||||
*puid = pc->uid;
|
||||
DEBUG(3,("fetch uid from cache %u -> %s\n",
|
||||
(unsigned int)*puid, sid_to_string(sid, psid)));
|
||||
(unsigned int)*puid, sid_string_static(psid)));
|
||||
DLIST_PROMOTE(uid_sid_cache_head, pc);
|
||||
return True;
|
||||
}
|
||||
@@ -261,10 +479,9 @@ static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
|
||||
|
||||
for (pc = gid_sid_cache_head; pc; pc = pc->next) {
|
||||
if (pc->gid == gid) {
|
||||
fstring sid;
|
||||
*psid = pc->sid;
|
||||
DEBUG(3,("fetch sid from gid cache %u -> %s\n",
|
||||
(unsigned int)gid, sid_to_string(sid, psid)));
|
||||
(unsigned int)gid, sid_string_static(psid)));
|
||||
DLIST_PROMOTE(gid_sid_cache_head, pc);
|
||||
return True;
|
||||
}
|
||||
@@ -282,10 +499,9 @@ static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
|
||||
|
||||
for (pc = gid_sid_cache_head; pc; pc = pc->next) {
|
||||
if (sid_compare(&pc->sid, psid) == 0) {
|
||||
fstring sid;
|
||||
*pgid = pc->gid;
|
||||
DEBUG(3,("fetch gid from cache %u -> %s\n",
|
||||
(unsigned int)*pgid, sid_to_string(sid, psid)));
|
||||
(unsigned int)*pgid, sid_string_static(psid)));
|
||||
DLIST_PROMOTE(gid_sid_cache_head, pc);
|
||||
return True;
|
||||
}
|
||||
@@ -331,7 +547,6 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
|
||||
|
||||
NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
|
||||
{
|
||||
fstring sid;
|
||||
uid_t low, high;
|
||||
|
||||
ZERO_STRUCTP(psid);
|
||||
@@ -348,7 +563,7 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
|
||||
if (winbind_uid_to_sid(psid, uid)) {
|
||||
|
||||
DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
|
||||
(unsigned int)uid, sid_to_string(sid, psid)));
|
||||
(unsigned int)uid, sid_string_static(psid)));
|
||||
|
||||
if (psid)
|
||||
store_uid_sid_cache(psid, uid);
|
||||
@@ -361,7 +576,8 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid)));
|
||||
DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid,
|
||||
sid_string_static(psid)));
|
||||
|
||||
store_uid_sid_cache(psid, uid);
|
||||
return NT_STATUS_OK;
|
||||
@@ -373,7 +589,6 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
|
||||
|
||||
NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
|
||||
{
|
||||
fstring sid;
|
||||
gid_t low, high;
|
||||
|
||||
ZERO_STRUCTP(psid);
|
||||
@@ -390,7 +605,7 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
|
||||
if (winbind_gid_to_sid(psid, gid)) {
|
||||
|
||||
DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
|
||||
(unsigned int)gid, sid_to_string(sid, psid)));
|
||||
(unsigned int)gid, sid_string_static(psid)));
|
||||
|
||||
if (psid)
|
||||
store_gid_sid_cache(psid, gid);
|
||||
@@ -403,7 +618,8 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid)));
|
||||
DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid,
|
||||
sid_string_static(psid)));
|
||||
|
||||
store_gid_sid_cache(psid, gid);
|
||||
return NT_STATUS_OK;
|
||||
@@ -415,7 +631,6 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
|
||||
|
||||
NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
|
||||
{
|
||||
fstring dom_name, name, sid_str;
|
||||
enum SID_NAME_USE name_type;
|
||||
|
||||
if (fetch_uid_from_cache(puid, psid))
|
||||
@@ -437,7 +652,7 @@ NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
|
||||
|
||||
/* If it is not our local domain, only hope is winbindd */
|
||||
|
||||
if ( !winbind_lookup_sid(psid, dom_name, name, &name_type) ) {
|
||||
if ( !winbind_lookup_sid(NULL, psid, NULL, NULL, &name_type) ) {
|
||||
DEBUG(10,("sid_to_uid: winbind lookup for non-local sid %s failed\n",
|
||||
sid_string_static(psid) ));
|
||||
|
||||
@@ -456,12 +671,12 @@ NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
|
||||
|
||||
if ( !winbind_sid_to_uid(puid, psid) ) {
|
||||
DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n",
|
||||
sid_to_string(sid_str, psid) ));
|
||||
sid_string_static(psid)));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
success:
|
||||
DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid),
|
||||
DEBUG(10,("sid_to_uid: %s -> %u\n", sid_string_static(psid),
|
||||
(unsigned int)*puid ));
|
||||
|
||||
store_uid_sid_cache(psid, *puid);
|
||||
@@ -475,7 +690,6 @@ success:
|
||||
|
||||
NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
|
||||
{
|
||||
fstring dom_name, name, sid_str;
|
||||
enum SID_NAME_USE name_type;
|
||||
|
||||
if (fetch_gid_from_cache(pgid, psid))
|
||||
@@ -489,8 +703,9 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
|
||||
if ( local_sid_to_gid(pgid, psid, &name_type) )
|
||||
goto success;
|
||||
|
||||
if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
|
||||
DEBUG(10,("sid_to_gid: no one knows the SID %s (tried local, then winbind)\n", sid_to_string(sid_str, psid)));
|
||||
if (!winbind_lookup_sid(NULL, psid, NULL, NULL, &name_type)) {
|
||||
DEBUG(10,("sid_to_gid: no one knows the SID %s (tried local, then "
|
||||
"winbind)\n", sid_string_static(psid)));
|
||||
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
@@ -514,12 +729,12 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
|
||||
|
||||
if ( !winbind_sid_to_gid(pgid, psid) ) {
|
||||
DEBUG(10,("sid_to_gid: winbind failed to allocate a new gid for sid %s\n",
|
||||
sid_to_string(sid_str, psid) ));
|
||||
sid_string_static(psid)));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
success:
|
||||
DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid),
|
||||
DEBUG(10,("sid_to_gid: %s -> %u\n", sid_string_static(psid),
|
||||
(unsigned int)*pgid ));
|
||||
|
||||
store_gid_sid_cache(psid, *pgid);
|
||||
|
||||
@@ -198,3 +198,27 @@ void reset_global_sam_sid(void)
|
||||
{
|
||||
SAFE_FREE(global_sam_sid);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Check if the SID is our domain SID (S-1-5-21-x-y-z).
|
||||
*****************************************************************/
|
||||
|
||||
BOOL sid_check_is_domain(const DOM_SID *sid)
|
||||
{
|
||||
return sid_equal(sid, get_global_sam_sid());
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Check if the SID is our domain SID (S-1-5-21-x-y-z).
|
||||
*****************************************************************/
|
||||
|
||||
BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
|
||||
{
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
|
||||
sid_copy(&dom_sid, sid);
|
||||
sid_split_rid(&dom_sid, &rid);
|
||||
|
||||
return sid_equal(&dom_sid, get_global_sam_sid());
|
||||
}
|
||||
|
||||
@@ -735,7 +735,7 @@ BOOL algorithmic_pdb_rid_is_user(uint32 rid)
|
||||
Look up a rid in the SAM we're responsible for (i.e. passdb)
|
||||
********************************************************************/
|
||||
|
||||
BOOL lookup_global_sam_rid(uint32 rid, fstring name,
|
||||
BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, char **name,
|
||||
enum SID_NAME_USE *psid_name_use)
|
||||
{
|
||||
SAM_ACCOUNT *sam_account = NULL;
|
||||
@@ -760,7 +760,7 @@ BOOL lookup_global_sam_rid(uint32 rid, fstring name,
|
||||
become_root();
|
||||
if (pdb_getsampwsid(sam_account, &sid)) {
|
||||
unbecome_root(); /* -----> EXIT BECOME_ROOT() */
|
||||
fstrcpy(name, pdb_get_username(sam_account));
|
||||
*name = talloc_strdup(mem_ctx, pdb_get_username(sam_account));
|
||||
*psid_name_use = SID_NAME_USER;
|
||||
|
||||
pdb_free_sam(&sam_account);
|
||||
@@ -784,14 +784,14 @@ BOOL lookup_global_sam_rid(uint32 rid, fstring name,
|
||||
map.nt_name));
|
||||
}
|
||||
|
||||
fstrcpy(name, map.nt_name);
|
||||
*name = talloc_strdup(mem_ctx, map.nt_name);
|
||||
*psid_name_use = map.sid_name_use;
|
||||
return True;
|
||||
}
|
||||
|
||||
if (rid == DOMAIN_USER_RID_ADMIN) {
|
||||
*psid_name_use = SID_NAME_USER;
|
||||
fstrcpy(name, "Administrator");
|
||||
*name = talloc_strdup(mem_ctx, "Administrator");
|
||||
return True;
|
||||
}
|
||||
|
||||
@@ -807,13 +807,15 @@ BOOL lookup_global_sam_rid(uint32 rid, fstring name,
|
||||
DEBUG(5,("lookup_global_sam_rid: looking up uid %u %s\n",
|
||||
(unsigned int)uid, pw ? "succeeded" : "failed" ));
|
||||
|
||||
if ( !pw )
|
||||
fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
|
||||
else
|
||||
fstrcpy( name, pw->pw_name );
|
||||
if ( !pw ) {
|
||||
*name = talloc_asprintf(mem_ctx, "unix_user.%u",
|
||||
(unsigned int)uid);
|
||||
} else {
|
||||
*name = talloc_strdup(mem_ctx, pw->pw_name );
|
||||
}
|
||||
|
||||
DEBUG(5,("lookup_global_sam_rid: found user %s for rid %u\n",
|
||||
name, (unsigned int)rid ));
|
||||
*name, (unsigned int)rid ));
|
||||
|
||||
*psid_name_use = SID_NAME_USER;
|
||||
|
||||
@@ -830,13 +832,15 @@ BOOL lookup_global_sam_rid(uint32 rid, fstring name,
|
||||
DEBUG(5,("lookup_global_sam_rid: looking up gid %u %s\n",
|
||||
(unsigned int)gid, gr ? "succeeded" : "failed" ));
|
||||
|
||||
if( !gr )
|
||||
fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
|
||||
else
|
||||
fstrcpy( name, gr->gr_name);
|
||||
if( !gr ) {
|
||||
*name = talloc_asprintf(mem_ctx, "unix_group.%u",
|
||||
(unsigned int)gid);
|
||||
} else {
|
||||
*name = talloc_strdup(mem_ctx, gr->gr_name);
|
||||
}
|
||||
|
||||
DEBUG(5,("lookup_global_sam_rid: found group %s for rid %u\n",
|
||||
name, (unsigned int)rid ));
|
||||
*name, (unsigned int)rid ));
|
||||
|
||||
/* assume algorithmic groups are domain global groups */
|
||||
|
||||
@@ -850,17 +854,13 @@ BOOL lookup_global_sam_rid(uint32 rid, fstring name,
|
||||
Convert a name into a SID. Used in the lookup name rpc.
|
||||
********************************************************************/
|
||||
|
||||
BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
|
||||
BOOL lookup_global_sam_name(const char *c_user, uint32_t *rid, enum SID_NAME_USE *type)
|
||||
{
|
||||
DOM_SID local_sid;
|
||||
DOM_SID sid;
|
||||
fstring user;
|
||||
SAM_ACCOUNT *sam_account = NULL;
|
||||
struct group *grp;
|
||||
GROUP_MAP map;
|
||||
|
||||
*psid_name_use = SID_NAME_UNKNOWN;
|
||||
|
||||
/*
|
||||
* user may be quoted a const string, and map_username and
|
||||
* friends can modify it. Make a modifiable copy. JRA.
|
||||
@@ -868,17 +868,6 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
|
||||
|
||||
fstrcpy(user, c_user);
|
||||
|
||||
sid_copy(&local_sid, get_global_sam_sid());
|
||||
|
||||
if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
|
||||
fstring sid_str;
|
||||
sid_copy( psid, &sid);
|
||||
sid_to_string(sid_str, &sid);
|
||||
DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
|
||||
(unsigned int)*psid_name_use ));
|
||||
return True;
|
||||
}
|
||||
|
||||
(void)map_username(user);
|
||||
|
||||
if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
|
||||
@@ -889,10 +878,28 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
|
||||
|
||||
become_root();
|
||||
if (pdb_getsampwnam(sam_account, user)) {
|
||||
unbecome_root();
|
||||
sid_copy(psid, pdb_get_user_sid(sam_account));
|
||||
*psid_name_use = SID_NAME_USER;
|
||||
const DOM_SID *user_sid;
|
||||
|
||||
unbecome_root();
|
||||
|
||||
user_sid = pdb_get_user_sid(sam_account);
|
||||
|
||||
if (!sid_check_is_in_our_domain(user_sid)) {
|
||||
DEBUG(0, ("User %s with invalid SID %s in passdb\n",
|
||||
user, sid_string_static(user_sid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
sid_peek_rid(user_sid, rid);
|
||||
|
||||
if (pdb_get_acct_ctrl(sam_account) &
|
||||
(ACB_DOMTRUST|ACB_WSTRUST|ACB_SVRTRUST)) {
|
||||
/* We have to filter them out in lsa_lookupnames,
|
||||
* indicate that this is not a real user. */
|
||||
*type = SID_NAME_COMPUTER;
|
||||
} else {
|
||||
*type = SID_NAME_USER;
|
||||
}
|
||||
pdb_free_sam(&sam_account);
|
||||
return True;
|
||||
}
|
||||
@@ -905,10 +912,23 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
|
||||
|
||||
/* check if it's a mapped group */
|
||||
if (pdb_getgrnam(&map, user)) {
|
||||
|
||||
unbecome_root();
|
||||
|
||||
/* BUILTIN groups are looked up elsewhere */
|
||||
if (!sid_check_is_in_our_domain(&map.sid)) {
|
||||
DEBUG(10, ("Found group %s (%s) not in our domain -- "
|
||||
"ignoring.", user,
|
||||
sid_string_static(&map.sid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* yes it's a mapped group */
|
||||
sid_copy(&local_sid, &map.sid);
|
||||
*psid_name_use = map.sid_name_use;
|
||||
} else {
|
||||
sid_peek_rid(&map.sid, rid);
|
||||
*type = map.sid_name_use;
|
||||
return True;
|
||||
}
|
||||
|
||||
/* it's not a mapped group */
|
||||
grp = getgrnam(user);
|
||||
if(!grp) {
|
||||
@@ -928,18 +948,15 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
|
||||
* JFM, 30/11/2001
|
||||
*/
|
||||
|
||||
if (pdb_getgrgid(&map, grp->gr_gid)){
|
||||
if (pdb_getgrgid(&map, grp->gr_gid)) {
|
||||
unbecome_root(); /* ---> exit form block */
|
||||
return False;
|
||||
}
|
||||
|
||||
sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
|
||||
*psid_name_use = SID_NAME_ALIAS;
|
||||
}
|
||||
unbecome_root();
|
||||
/* END ROOT BLOCK */
|
||||
|
||||
sid_copy( psid, &local_sid);
|
||||
*rid = pdb_gid_to_group_rid(grp->gr_gid);
|
||||
*type = SID_NAME_ALIAS;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@@ -699,6 +699,25 @@ static NTSTATUS context_lookup_rids(struct pdb_context *context,
|
||||
rids, pp_names, pp_attrs);
|
||||
}
|
||||
|
||||
static NTSTATUS context_lookup_names(struct pdb_context *context,
|
||||
const DOM_SID *domain_sid,
|
||||
size_t num_names,
|
||||
const char **pp_names,
|
||||
uint32 *rids,
|
||||
uint32 *pp_attrs)
|
||||
{
|
||||
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
if ((!context) || (!context->pdb_methods)) {
|
||||
DEBUG(0, ("invalid pdb_context specified!\n"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return context->pdb_methods->lookup_names(context->pdb_methods,
|
||||
domain_sid, num_names,
|
||||
pp_names, rids, pp_attrs);
|
||||
}
|
||||
|
||||
static NTSTATUS context_get_account_policy(struct pdb_context *context,
|
||||
int policy_index, uint32 *value)
|
||||
{
|
||||
@@ -906,6 +925,7 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
|
||||
(*context)->pdb_enum_aliasmem = context_enum_aliasmem;
|
||||
(*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
|
||||
(*context)->pdb_lookup_rids = context_lookup_rids;
|
||||
(*context)->pdb_lookup_names = context_lookup_names;
|
||||
|
||||
(*context)->pdb_get_account_policy = context_get_account_policy;
|
||||
(*context)->pdb_set_account_policy = context_set_account_policy;
|
||||
@@ -1413,6 +1433,22 @@ NTSTATUS pdb_lookup_rids(const DOM_SID *domain_sid,
|
||||
num_rids, rids, names, attrs);
|
||||
}
|
||||
|
||||
NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
|
||||
int num_names,
|
||||
const char **names,
|
||||
uint32 *rids,
|
||||
uint32 *attrs)
|
||||
{
|
||||
struct pdb_context *pdb_context = pdb_get_static_context(False);
|
||||
|
||||
if (!pdb_context) {
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return pdb_context->pdb_lookup_names(pdb_context, domain_sid,
|
||||
num_names, names, rids, attrs);
|
||||
}
|
||||
|
||||
BOOL pdb_get_account_policy(int policy_index, uint32 *value)
|
||||
{
|
||||
struct pdb_context *pdb_context = pdb_get_static_context(False);
|
||||
@@ -1655,14 +1691,11 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
|
||||
if (sid_check_is_builtin(domain_sid)) {
|
||||
|
||||
for (i=0; i<num_rids; i++) {
|
||||
fstring name;
|
||||
char *name;
|
||||
|
||||
if (lookup_builtin_rid(rids[i], name)) {
|
||||
if (lookup_builtin_rid(names, rids[i], &name)) {
|
||||
attrs[i] = SID_NAME_ALIAS;
|
||||
names[i] = talloc_strdup(names, name);
|
||||
if (names[i] == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
names[i] = name;
|
||||
DEBUG(5,("lookup_rids: %s:%d\n",
|
||||
names[i], attrs[i]));
|
||||
have_mapped = True;
|
||||
@@ -1680,14 +1713,69 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
|
||||
}
|
||||
|
||||
for (i = 0; i < num_rids; i++) {
|
||||
fstring tmpname;
|
||||
enum SID_NAME_USE type;
|
||||
char *name;
|
||||
|
||||
if (lookup_global_sam_rid(rids[i], tmpname, &type)) {
|
||||
attrs[i] = (uint32)type;
|
||||
names[i] = talloc_strdup(names, tmpname);
|
||||
if (names[i] == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i])) {
|
||||
names[i] = name;
|
||||
DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
|
||||
have_mapped = True;
|
||||
} else {
|
||||
have_unmapped = True;
|
||||
attrs[i] = SID_NAME_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
result = NT_STATUS_NONE_MAPPED;
|
||||
|
||||
if (have_mapped)
|
||||
result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
|
||||
const DOM_SID *domain_sid,
|
||||
int num_names,
|
||||
const char **names,
|
||||
uint32 *rids,
|
||||
uint32 *attrs)
|
||||
{
|
||||
int i;
|
||||
NTSTATUS result;
|
||||
BOOL have_mapped = False;
|
||||
BOOL have_unmapped = False;
|
||||
|
||||
if (sid_check_is_builtin(domain_sid)) {
|
||||
|
||||
for (i=0; i<num_names; i++) {
|
||||
uint32 rid;
|
||||
|
||||
if (lookup_builtin_name(names[i], &rid)) {
|
||||
attrs[i] = SID_NAME_ALIAS;
|
||||
rids[i] = rid;
|
||||
DEBUG(5,("lookup_rids: %s:%d\n",
|
||||
names[i], attrs[i]));
|
||||
have_mapped = True;
|
||||
} else {
|
||||
have_unmapped = True;
|
||||
attrs[i] = SID_NAME_UNKNOWN;
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Should not happen, but better check once too many */
|
||||
if (!sid_check_is_domain(domain_sid)) {
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_names; i++) {
|
||||
char *name;
|
||||
|
||||
if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i])) {
|
||||
names[i] = name;
|
||||
DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
|
||||
have_mapped = True;
|
||||
} else {
|
||||
|
||||
@@ -359,7 +359,7 @@ BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
|
||||
if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
|
||||
|
||||
/* domain sid */
|
||||
sid_copy(sid, &pass.domain_sid);
|
||||
if (sid != NULL) sid_copy(sid, &pass.domain_sid);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
110
source/passdb/util_builtin.c
Normal file
110
source/passdb/util_builtin.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Translate BUILTIN names to SIDs and vice versa
|
||||
Copyright (C) Volker Lendecke 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
struct rid_name_map {
|
||||
uint32 rid;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static const struct rid_name_map builtin_aliases[] = {
|
||||
{ BUILTIN_ALIAS_RID_ADMINS, "Administrators" },
|
||||
{ BUILTIN_ALIAS_RID_USERS, "Users" },
|
||||
{ BUILTIN_ALIAS_RID_GUESTS, "Guests" },
|
||||
{ BUILTIN_ALIAS_RID_POWER_USERS, "Power Users" },
|
||||
{ BUILTIN_ALIAS_RID_ACCOUNT_OPS, "Account Operators" },
|
||||
{ BUILTIN_ALIAS_RID_SYSTEM_OPS, "Server Operators" },
|
||||
{ BUILTIN_ALIAS_RID_PRINT_OPS, "Print Operators" },
|
||||
{ BUILTIN_ALIAS_RID_BACKUP_OPS, "Backup Operators" },
|
||||
{ BUILTIN_ALIAS_RID_REPLICATOR, "Replicator" },
|
||||
{ BUILTIN_ALIAS_RID_RAS_SERVERS, "RAS Servers" },
|
||||
{ BUILTIN_ALIAS_RID_PRE_2K_ACCESS, "Pre-Windows 2000 Compatible Access" },
|
||||
{ 0, NULL}};
|
||||
|
||||
/*******************************************************************
|
||||
Look up a rid in the BUILTIN domain
|
||||
********************************************************************/
|
||||
BOOL lookup_builtin_rid(TALLOC_CTX *mem_ctx, uint32 rid, char **name)
|
||||
{
|
||||
const struct rid_name_map *aliases = builtin_aliases;
|
||||
|
||||
while (aliases->name != NULL) {
|
||||
if (rid == aliases->rid) {
|
||||
*name = talloc_strdup(mem_ctx, aliases->name);
|
||||
return True;
|
||||
}
|
||||
aliases++;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Look up a name in the BUILTIN domain
|
||||
********************************************************************/
|
||||
BOOL lookup_builtin_name(const char *name, uint32 *rid)
|
||||
{
|
||||
const struct rid_name_map *aliases = builtin_aliases;
|
||||
|
||||
while (aliases->name != NULL) {
|
||||
if (strequal(name, aliases->name)) {
|
||||
*rid = aliases->rid;
|
||||
return True;
|
||||
}
|
||||
aliases++;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Return the name of the BUILTIN domain
|
||||
*****************************************************************/
|
||||
|
||||
const char *builtin_domain_name(void)
|
||||
{
|
||||
return "BUILTIN";
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Check if the SID is the builtin SID (S-1-5-32).
|
||||
*****************************************************************/
|
||||
|
||||
BOOL sid_check_is_builtin(const DOM_SID *sid)
|
||||
{
|
||||
return sid_equal(sid, &global_sid_Builtin);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Check if the SID is one of the builtin SIDs (S-1-5-32-a).
|
||||
*****************************************************************/
|
||||
|
||||
BOOL sid_check_is_in_builtin(const DOM_SID *sid)
|
||||
{
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
|
||||
sid_copy(&dom_sid, sid);
|
||||
sid_split_rid(&dom_sid, &rid);
|
||||
|
||||
return sid_equal(&dom_sid, &global_sid_Builtin);
|
||||
}
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Samba utility functions
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
|
||||
Copyright (C) Jeremy Allison 1999
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#define MAX_SID_NAMES 7
|
||||
|
||||
typedef struct _known_sid_users {
|
||||
uint32 rid;
|
||||
enum SID_NAME_USE sid_name_use;
|
||||
const char *known_user_name;
|
||||
} known_sid_users;
|
||||
|
||||
struct sid_name_map_info
|
||||
{
|
||||
const DOM_SID *sid;
|
||||
const char *name;
|
||||
const known_sid_users *known_users;
|
||||
};
|
||||
|
||||
static const known_sid_users everyone_users[] = {
|
||||
{ 0, SID_NAME_WKN_GRP, "Everyone" },
|
||||
{0, (enum SID_NAME_USE)0, NULL}};
|
||||
|
||||
static const known_sid_users creator_owner_users[] = {
|
||||
{ 0, SID_NAME_WKN_GRP, "Creator Owner" },
|
||||
{ 1, SID_NAME_WKN_GRP, "Creator Group" },
|
||||
{0, (enum SID_NAME_USE)0, NULL}};
|
||||
|
||||
static const known_sid_users nt_authority_users[] = {
|
||||
{ 1, SID_NAME_WKN_GRP, "Dialup" },
|
||||
{ 2, SID_NAME_WKN_GRP, "Network"},
|
||||
{ 3, SID_NAME_WKN_GRP, "Batch"},
|
||||
{ 4, SID_NAME_WKN_GRP, "Interactive"},
|
||||
{ 6, SID_NAME_WKN_GRP, "Service"},
|
||||
{ 7, SID_NAME_WKN_GRP, "AnonymousLogon"},
|
||||
{ 8, SID_NAME_WKN_GRP, "Proxy"},
|
||||
{ 9, SID_NAME_WKN_GRP, "ServerLogon"},
|
||||
{ 10, SID_NAME_WKN_GRP, "Self"},
|
||||
{ 11, SID_NAME_WKN_GRP, "Authenticated Users"},
|
||||
{ 12, SID_NAME_WKN_GRP, "Restricted"},
|
||||
{ 13, SID_NAME_WKN_GRP, "Terminal Server User"},
|
||||
{ 14, SID_NAME_WKN_GRP, "Remote Interactive Logon"},
|
||||
{ 15, SID_NAME_WKN_GRP, "This Organization"},
|
||||
{ 18, SID_NAME_WKN_GRP, "SYSTEM"},
|
||||
{ 19, SID_NAME_WKN_GRP, "Local Service"},
|
||||
{ 20, SID_NAME_WKN_GRP, "Network Service"},
|
||||
{ 0, (enum SID_NAME_USE)0, NULL}};
|
||||
|
||||
static const known_sid_users builtin_groups[] = {
|
||||
{ BUILTIN_ALIAS_RID_ADMINS, SID_NAME_ALIAS, "Administrators" },
|
||||
{ BUILTIN_ALIAS_RID_USERS, SID_NAME_ALIAS, "Users" },
|
||||
{ BUILTIN_ALIAS_RID_GUESTS, SID_NAME_ALIAS, "Guests" },
|
||||
{ BUILTIN_ALIAS_RID_POWER_USERS, SID_NAME_ALIAS, "Power Users" },
|
||||
{ BUILTIN_ALIAS_RID_ACCOUNT_OPS, SID_NAME_ALIAS, "Account Operators" },
|
||||
{ BUILTIN_ALIAS_RID_SYSTEM_OPS, SID_NAME_ALIAS, "Server Operators" },
|
||||
{ BUILTIN_ALIAS_RID_PRINT_OPS, SID_NAME_ALIAS, "Print Operators" },
|
||||
{ BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" },
|
||||
{ BUILTIN_ALIAS_RID_REPLICATOR, SID_NAME_ALIAS, "Replicator" },
|
||||
{ BUILTIN_ALIAS_RID_RAS_SERVERS, SID_NAME_ALIAS, "RAS Servers" },
|
||||
{ BUILTIN_ALIAS_RID_PRE_2K_ACCESS, SID_NAME_ALIAS, "Pre-Windows 2000 Compatible Access" },
|
||||
{ 0, (enum SID_NAME_USE)0, NULL}};
|
||||
|
||||
static struct sid_name_map_info special_domains[] = {
|
||||
{ &global_sid_Builtin, "BUILTIN", builtin_groups },
|
||||
{ &global_sid_World_Domain, "", everyone_users },
|
||||
{ &global_sid_Creator_Owner_Domain, "", creator_owner_users },
|
||||
{ &global_sid_NT_Authority, "NT Authority", nt_authority_users },
|
||||
{ NULL, NULL, NULL }};
|
||||
|
||||
/**************************************************************************
|
||||
Turns a domain SID into a name, returned in the nt_domain argument.
|
||||
***************************************************************************/
|
||||
|
||||
BOOL map_domain_sid_to_name(const DOM_SID *sid, fstring 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));
|
||||
|
||||
while (special_domains[i].sid != NULL) {
|
||||
DEBUG(5,("map_domain_sid_to_name: compare: %s\n",
|
||||
sid_string_static(special_domains[i].sid)));
|
||||
if (sid_equal(special_domains[i].sid, sid)) {
|
||||
fstrcpy(nt_domain, special_domains[i].name);
|
||||
DEBUG(5,("map_domain_sid_to_name: found '%s'\n",
|
||||
nt_domain));
|
||||
return True;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n",
|
||||
sid_string_static(sid)));
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Looks up a known username from one of the known domains.
|
||||
***************************************************************************/
|
||||
|
||||
BOOL lookup_special_sid(const DOM_SID *sid, const char **domain,
|
||||
const char **name, enum SID_NAME_USE *type)
|
||||
{
|
||||
int i;
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
const known_sid_users *users = NULL;
|
||||
|
||||
sid_copy(&dom_sid, sid);
|
||||
if (!sid_split_rid(&dom_sid, &rid)) {
|
||||
DEBUG(2, ("Could not split rid from SID\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
for (i=0; special_domains[i].sid != NULL; i++) {
|
||||
if (sid_equal(&dom_sid, special_domains[i].sid)) {
|
||||
*domain = special_domains[i].name;
|
||||
users = special_domains[i].known_users;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (users == NULL) {
|
||||
DEBUG(10, ("SID %s is no special sid\n",
|
||||
sid_string_static(sid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
for (i=0; users[i].known_user_name != NULL; i++) {
|
||||
if (rid == users[i].rid) {
|
||||
*name = users[i].known_user_name;
|
||||
*type = users[i].sid_name_use;
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(10, ("RID of special SID %s not found\n",
|
||||
sid_string_static(sid)));
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Look up a rid in the BUILTIN domain
|
||||
********************************************************************/
|
||||
BOOL lookup_builtin_rid(uint32 rid, fstring name)
|
||||
{
|
||||
const known_sid_users *aliases = builtin_groups;
|
||||
int i;
|
||||
|
||||
for (i=0; aliases[i].known_user_name != NULL; i++) {
|
||||
if (rid == aliases[i].rid) {
|
||||
fstrcpy(name, aliases[i].known_user_name);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Check if the SID is our domain SID (S-1-5-21-x-y-z).
|
||||
*****************************************************************/
|
||||
|
||||
BOOL sid_check_is_domain(const DOM_SID *sid)
|
||||
{
|
||||
return sid_equal(sid, get_global_sam_sid());
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Check if the SID is our domain SID (S-1-5-21-x-y-z).
|
||||
*****************************************************************/
|
||||
|
||||
BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
|
||||
{
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
|
||||
sid_copy(&dom_sid, sid);
|
||||
sid_split_rid(&dom_sid, &rid);
|
||||
|
||||
return sid_equal(&dom_sid, get_global_sam_sid());
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Try and map a name to one of the well known SIDs.
|
||||
***************************************************************************/
|
||||
|
||||
BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char *name)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));
|
||||
|
||||
for (i=0; special_domains[i].sid != NULL; i++) {
|
||||
const known_sid_users *users = special_domains[i].known_users;
|
||||
|
||||
if (users == NULL)
|
||||
continue;
|
||||
|
||||
for (j=0; users[j].known_user_name != NULL; j++) {
|
||||
if ( strequal(users[j].known_user_name, name) ) {
|
||||
sid_copy(sid, special_domains[i].sid);
|
||||
sid_append_rid(sid, users[j].rid);
|
||||
*use = users[j].sid_name_use;
|
||||
return True;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
149
source/passdb/util_wellknown.c
Normal file
149
source/passdb/util_wellknown.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Lookup routines for well-known SIDs
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
|
||||
Copyright (C) Jeremy Allison 1999
|
||||
Copyright (C) Volker Lendecke 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
struct rid_name_map {
|
||||
uint32 rid;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct sid_name_map_info
|
||||
{
|
||||
const DOM_SID *sid;
|
||||
const char *name;
|
||||
const struct rid_name_map *known_users;
|
||||
};
|
||||
|
||||
static const struct rid_name_map everyone_users[] = {
|
||||
{ 0, "Everyone" },
|
||||
{ 0, NULL}};
|
||||
|
||||
static const struct rid_name_map creator_owner_users[] = {
|
||||
{ 0, "Creator Owner" },
|
||||
{ 1, "Creator Group" },
|
||||
{ 0, NULL}};
|
||||
|
||||
static const struct rid_name_map nt_authority_users[] = {
|
||||
{ 1, "Dialup" },
|
||||
{ 2, "Network"},
|
||||
{ 3, "Batch"},
|
||||
{ 4, "Interactive"},
|
||||
{ 6, "Service"},
|
||||
{ 7, "AnonymousLogon"},
|
||||
{ 8, "Proxy"},
|
||||
{ 9, "ServerLogon"},
|
||||
{ 10, "Self"},
|
||||
{ 11, "Authenticated Users"},
|
||||
{ 12, "Restricted"},
|
||||
{ 13, "Terminal Server User"},
|
||||
{ 14, "Remote Interactive Logon"},
|
||||
{ 15, "This Organization"},
|
||||
{ 18, "SYSTEM"},
|
||||
{ 19, "Local Service"},
|
||||
{ 20, "Network Service"},
|
||||
{ 0, NULL}};
|
||||
|
||||
static struct sid_name_map_info special_domains[] = {
|
||||
{ &global_sid_World_Domain, "", everyone_users },
|
||||
{ &global_sid_Creator_Owner_Domain, "", creator_owner_users },
|
||||
{ &global_sid_NT_Authority, "NT Authority", nt_authority_users },
|
||||
{ NULL, NULL, NULL }};
|
||||
|
||||
/**************************************************************************
|
||||
Looks up a known username from one of the known domains.
|
||||
***************************************************************************/
|
||||
|
||||
BOOL lookup_wellknown_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
|
||||
char **domain, char **name)
|
||||
{
|
||||
int i;
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
const struct rid_name_map *users = NULL;
|
||||
|
||||
sid_copy(&dom_sid, sid);
|
||||
if (!sid_split_rid(&dom_sid, &rid)) {
|
||||
DEBUG(2, ("Could not split rid from SID\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
for (i=0; special_domains[i].sid != NULL; i++) {
|
||||
if (sid_equal(&dom_sid, special_domains[i].sid)) {
|
||||
*domain = talloc_strdup(mem_ctx,
|
||||
special_domains[i].name);
|
||||
users = special_domains[i].known_users;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (users == NULL) {
|
||||
DEBUG(10, ("SID %s is no special sid\n",
|
||||
sid_string_static(sid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
for (i=0; users[i].name != NULL; i++) {
|
||||
if (rid == users[i].rid) {
|
||||
*name = talloc_strdup(mem_ctx, users[i].name);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(10, ("RID of special SID %s not found\n",
|
||||
sid_string_static(sid)));
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Try and map a name to one of the well known SIDs.
|
||||
***************************************************************************/
|
||||
|
||||
BOOL lookup_wellknown_name(TALLOC_CTX *mem_ctx, const char *name,
|
||||
DOM_SID *sid, char **domain)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));
|
||||
|
||||
for (i=0; special_domains[i].sid != NULL; i++) {
|
||||
const struct rid_name_map *users =
|
||||
special_domains[i].known_users;
|
||||
|
||||
if (users == NULL)
|
||||
continue;
|
||||
|
||||
for (j=0; users[j].name != NULL; j++) {
|
||||
if ( strequal(users[j].name, name) ) {
|
||||
sid_copy(sid, special_domains[i].sid);
|
||||
sid_append_rid(sid, users[j].rid);
|
||||
*domain = talloc_strdup(
|
||||
mem_ctx, special_domains[i].name);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
@@ -135,67 +135,75 @@ static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
|
||||
init_lsa_rid2s
|
||||
***************************************************************************/
|
||||
|
||||
static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
|
||||
static int init_lsa_rid2s(TALLOC_CTX *mem_ctx,
|
||||
DOM_R_REF *ref, DOM_RID2 *rid2,
|
||||
int num_entries, UNISTR2 *name,
|
||||
uint32 *mapped_count, BOOL endian)
|
||||
int flags)
|
||||
{
|
||||
int i;
|
||||
int total = 0;
|
||||
*mapped_count = 0;
|
||||
int mapped_count, i;
|
||||
|
||||
SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
|
||||
|
||||
mapped_count = 0;
|
||||
|
||||
become_root(); /* lookup_name can require root privs */
|
||||
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
BOOL status = False;
|
||||
DOM_SID sid;
|
||||
uint32 rid = 0xffffffff;
|
||||
int dom_idx = -1;
|
||||
pstring full_name;
|
||||
fstring dom_name, user;
|
||||
enum SID_NAME_USE name_type = SID_NAME_UNKNOWN;
|
||||
uint32 rid;
|
||||
int dom_idx;
|
||||
char *full_name, *domain;
|
||||
enum SID_NAME_USE type = SID_NAME_UNKNOWN;
|
||||
|
||||
/* Split name into domain and user component */
|
||||
|
||||
unistr2_to_ascii(full_name, &name[i], sizeof(full_name));
|
||||
split_domain_name(full_name, dom_name, user);
|
||||
|
||||
/* Lookup name */
|
||||
if (rpcstr_pull_unistr2_talloc(mem_ctx, &full_name,
|
||||
&name[i]) < 0) {
|
||||
DEBUG(0, ("pull_ucs2_talloc failed\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name));
|
||||
|
||||
status = lookup_name(dom_name, user, &sid, &name_type);
|
||||
/* We can ignore the result of lookup_name, it will not touch
|
||||
"type" if it's not successful */
|
||||
|
||||
if((name_type == SID_NAME_UNKNOWN) && (lp_server_role() == ROLE_DOMAIN_MEMBER) && (strncmp(dom_name, full_name, strlen(dom_name)) != 0)) {
|
||||
DEBUG(5, ("init_lsa_rid2s: domain name not provided and local account not found, using member domain\n"));
|
||||
fstrcpy(dom_name, lp_workgroup());
|
||||
status = lookup_name(dom_name, user, &sid, &name_type);
|
||||
}
|
||||
|
||||
if (name_type == SID_NAME_WKN_GRP) {
|
||||
/* BUILTIN aliases are still aliases :-) */
|
||||
name_type = SID_NAME_ALIAS;
|
||||
}
|
||||
lookup_name(mem_ctx, full_name, flags, &domain, NULL,
|
||||
&sid, &type);
|
||||
|
||||
DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" :
|
||||
"not found"));
|
||||
|
||||
if (status && name_type != SID_NAME_UNKNOWN) {
|
||||
sid_split_rid(&sid, &rid);
|
||||
dom_idx = init_dom_ref(ref, dom_name, &sid);
|
||||
(*mapped_count)++;
|
||||
} else {
|
||||
dom_idx = -1;
|
||||
rid = 0;
|
||||
name_type = SID_NAME_UNKNOWN;
|
||||
switch (type) {
|
||||
case SID_NAME_USER:
|
||||
case SID_NAME_DOM_GRP:
|
||||
case SID_NAME_DOMAIN:
|
||||
case SID_NAME_ALIAS:
|
||||
case SID_NAME_WKN_GRP:
|
||||
/* Leave these unchanged */
|
||||
break;
|
||||
default:
|
||||
/* Don't hand out anything but the list above */
|
||||
type = SID_NAME_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
init_dom_rid2(&rid2[total], rid, name_type, dom_idx);
|
||||
total++;
|
||||
rid = 0;
|
||||
dom_idx = -1;
|
||||
|
||||
if (type != SID_NAME_UNKNOWN) {
|
||||
sid_split_rid(&sid, &rid);
|
||||
dom_idx = init_dom_ref(ref, domain, &sid);
|
||||
mapped_count++;
|
||||
}
|
||||
|
||||
init_dom_rid2(&rid2[i], rid, type, dom_idx);
|
||||
}
|
||||
|
||||
unbecome_root();
|
||||
|
||||
return mapped_count;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
@@ -250,42 +258,44 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME
|
||||
DOM_SID find_sid = sid[i].sid;
|
||||
uint32 rid = 0xffffffff;
|
||||
int dom_idx = -1;
|
||||
fstring name, dom_name;
|
||||
enum SID_NAME_USE sid_name_use = (enum SID_NAME_USE)0;
|
||||
char *name, *domain;
|
||||
enum SID_NAME_USE type = SID_NAME_UNKNOWN;
|
||||
|
||||
sid_to_string(name, &find_sid);
|
||||
DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name));
|
||||
DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n",
|
||||
sid_string_static(&find_sid)));
|
||||
|
||||
/* Lookup sid from winbindd */
|
||||
|
||||
status = lookup_sid(&find_sid, dom_name, name, &sid_name_use);
|
||||
status = lookup_sid(ctx, &find_sid, &domain, &name, &type);
|
||||
|
||||
DEBUG(5, ("init_lsa_trans_names: %s\n", status ? "found" :
|
||||
"not found"));
|
||||
|
||||
if (!status) {
|
||||
sid_name_use = SID_NAME_UNKNOWN;
|
||||
memset(dom_name, '\0', sizeof(dom_name));
|
||||
sid_to_string(name, &find_sid);
|
||||
type = SID_NAME_UNKNOWN;
|
||||
domain = talloc_strdup(ctx, "");
|
||||
name = talloc_strdup(ctx,
|
||||
sid_string_static(&find_sid));
|
||||
dom_idx = -1;
|
||||
|
||||
DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to "
|
||||
"referenced list.\n", name ));
|
||||
DEBUG(10,("init_lsa_trans_names: added unknown user "
|
||||
"'%s' to referenced list.\n", name ));
|
||||
} else {
|
||||
(*mapped_count)++;
|
||||
/* Store domain sid in ref array */
|
||||
if (find_sid.num_auths == 5) {
|
||||
sid_split_rid(&find_sid, &rid);
|
||||
}
|
||||
dom_idx = init_dom_ref(ref, dom_name, &find_sid);
|
||||
dom_idx = init_dom_ref(ref, domain, &find_sid);
|
||||
|
||||
DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' (%d) to referenced list.\n",
|
||||
sid_type_lookup(sid_name_use), dom_name, name, sid_name_use ));
|
||||
DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' "
|
||||
"(%d) to referenced list.\n",
|
||||
sid_type_lookup(type), domain, name, type));
|
||||
|
||||
}
|
||||
|
||||
init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
|
||||
sid_name_use, name, dom_idx);
|
||||
type, name, dom_idx);
|
||||
total++;
|
||||
}
|
||||
|
||||
@@ -697,12 +707,18 @@ NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP
|
||||
DOM_R_REF *ref;
|
||||
DOM_RID2 *rids;
|
||||
uint32 mapped_count = 0;
|
||||
int flags = 0;
|
||||
|
||||
if (num_entries > MAX_LOOKUP_SIDS) {
|
||||
num_entries = MAX_LOOKUP_SIDS;
|
||||
DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
|
||||
}
|
||||
|
||||
/* Probably the lookup_level is some sort of bitmask. */
|
||||
if (q_u->lookup_level == 1) {
|
||||
flags = LOOKUP_NAME_ALL;
|
||||
}
|
||||
|
||||
ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
|
||||
rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries);
|
||||
|
||||
@@ -720,10 +736,11 @@ NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP
|
||||
if (!ref || !rids)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
/* set up the LSA Lookup RIDs response */
|
||||
mapped_count = init_lsa_rid2s(p->mem_ctx, ref, rids, num_entries,
|
||||
names, flags);
|
||||
done:
|
||||
|
||||
/* set up the LSA Lookup RIDs response */
|
||||
init_lsa_rid2s(ref, rids, num_entries, names, &mapped_count, p->endian);
|
||||
if (NT_STATUS_IS_OK(r_u->status)) {
|
||||
if (mapped_count == 0)
|
||||
r_u->status = NT_STATUS_NONE_MAPPED;
|
||||
@@ -1109,15 +1126,13 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVS
|
||||
NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
|
||||
{
|
||||
struct lsa_info *info=NULL;
|
||||
fstring name, dom_name;
|
||||
enum SID_NAME_USE type;
|
||||
|
||||
/* find the connection policy handle. */
|
||||
|
||||
if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
|
||||
if (!lookup_sid(&info->sid, dom_name, name, &type))
|
||||
if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL))
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
|
||||
/*
|
||||
|
||||
@@ -1366,9 +1366,7 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM
|
||||
NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
|
||||
{
|
||||
uint32 rid[MAX_SAM_ENTRIES];
|
||||
uint32 local_rid;
|
||||
enum SID_NAME_USE type[MAX_SAM_ENTRIES];
|
||||
enum SID_NAME_USE local_type;
|
||||
int i;
|
||||
int num_rids = q_u->num_names2;
|
||||
DOM_SID pol_sid;
|
||||
@@ -1400,41 +1398,29 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
|
||||
|
||||
for (i = 0; i < num_rids; i++) {
|
||||
fstring name;
|
||||
DOM_SID sid;
|
||||
int ret;
|
||||
|
||||
r_u->status = NT_STATUS_NONE_MAPPED;
|
||||
type[i] = SID_NAME_UNKNOWN;
|
||||
|
||||
rid [i] = 0xffffffff;
|
||||
type[i] = SID_NAME_UNKNOWN;
|
||||
|
||||
ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
|
||||
|
||||
/*
|
||||
* we are only looking for a name
|
||||
* the SID we get back can be outside
|
||||
* the scope of the pol_sid
|
||||
*
|
||||
* in clear: it prevents to reply to domain\group: yes
|
||||
* when only builtin\group exists.
|
||||
*
|
||||
* a cleaner code is to add the sid of the domain we're looking in
|
||||
* to the local_lookup_name function.
|
||||
*/
|
||||
|
||||
if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
|
||||
sid_split_rid(&sid, &local_rid);
|
||||
|
||||
if (sid_equal(&sid, &pol_sid)) {
|
||||
rid[i]=local_rid;
|
||||
|
||||
/* Windows does not return WKN_GRP here, even
|
||||
* on lookups in builtin */
|
||||
type[i] = (local_type == SID_NAME_WKN_GRP) ?
|
||||
SID_NAME_ALIAS : local_type;
|
||||
|
||||
r_u->status = NT_STATUS_OK;
|
||||
if (ret <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sid_check_is_builtin(&pol_sid)) {
|
||||
if (lookup_builtin_name(name, &rid[i])) {
|
||||
type[i] = SID_NAME_ALIAS;
|
||||
}
|
||||
} else {
|
||||
lookup_global_sam_name(name, &rid[i], &type[i]);
|
||||
}
|
||||
|
||||
if (type[i] != SID_NAME_UNKNOWN) {
|
||||
r_u->status = NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2247,6 +2233,41 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
|
||||
return r_u->status;
|
||||
}
|
||||
|
||||
/* W2k3 seems to use the same check for all 3 objects that can be created via
|
||||
* SAMR, if you try to create for example "Dialup" as an alias it says
|
||||
* "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
|
||||
* database. */
|
||||
|
||||
static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
|
||||
{
|
||||
enum SID_NAME_USE type;
|
||||
BOOL result;
|
||||
|
||||
become_root();
|
||||
/* Lookup in our local databases (only LOOKUP_NAME_ISOLATED set)
|
||||
* whether the name already exists */
|
||||
result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_ISOLATED,
|
||||
NULL, NULL, NULL, &type);
|
||||
unbecome_root();
|
||||
|
||||
if (!result) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
DEBUG(5, ("trying to create %s, exists as %s\n",
|
||||
new_name, sid_type_lookup(type)));
|
||||
|
||||
if (type == SID_NAME_DOM_GRP) {
|
||||
return NT_STATUS_GROUP_EXISTS;
|
||||
}
|
||||
if (type == SID_NAME_ALIAS) {
|
||||
return NT_STATUS_ALIAS_EXISTS;
|
||||
}
|
||||
|
||||
/* Yes, the default is NT_STATUS_USER_EXISTS */
|
||||
return NT_STATUS_USER_EXISTS;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
_samr_create_user
|
||||
Create an account, can be either a normal user or a machine.
|
||||
@@ -2294,19 +2315,11 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
|
||||
rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
|
||||
strlower_m(account);
|
||||
|
||||
pdb_init_sam(&sam_pass);
|
||||
|
||||
become_root();
|
||||
ret = pdb_getsampwnam(sam_pass, account);
|
||||
unbecome_root();
|
||||
if (ret == True) {
|
||||
/* this account exists: say so */
|
||||
pdb_free_sam(&sam_pass);
|
||||
return NT_STATUS_USER_EXISTS;
|
||||
nt_status = can_create(p->mem_ctx, account);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
pdb_free_sam(&sam_pass);
|
||||
|
||||
/*********************************************************************
|
||||
* HEADS UP! If we have to create a new user account, we have to get
|
||||
* a new RID from somewhere. This used to be done by the passdb
|
||||
@@ -2776,7 +2789,7 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
|
||||
/* append the alias' RID to it */
|
||||
|
||||
if (!sid_append_rid(&sid, alias_rid))
|
||||
return NT_STATUS_NO_SUCH_USER;
|
||||
return NT_STATUS_NO_SUCH_ALIAS;
|
||||
|
||||
/*check if access can be granted as requested by client. */
|
||||
|
||||
@@ -2793,12 +2806,21 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
|
||||
if ( !NT_STATUS_IS_OK(status) )
|
||||
return status;
|
||||
|
||||
/*
|
||||
* we should check if the rid really exist !!!
|
||||
* JFM.
|
||||
*/
|
||||
{
|
||||
/* Check we actually have the requested alias */
|
||||
enum SID_NAME_USE type;
|
||||
BOOL result;
|
||||
|
||||
/* associate the user's SID with the new handle. */
|
||||
become_root();
|
||||
result = lookup_sid(NULL, &sid, NULL, NULL, &type);
|
||||
unbecome_root();
|
||||
|
||||
if (!result || (type != SID_NAME_ALIAS)) {
|
||||
return NT_STATUS_NO_SUCH_ALIAS;
|
||||
}
|
||||
}
|
||||
|
||||
/* associate the alias SID with the new handle. */
|
||||
if ((info = get_samr_info_by_sid(&sid)) == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
@@ -2814,12 +2836,11 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
|
||||
/*******************************************************************
|
||||
set_user_info_7
|
||||
********************************************************************/
|
||||
static NTSTATUS set_user_info_7(const SAM_USER_INFO_7 *id7, SAM_ACCOUNT *pwd)
|
||||
static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
|
||||
const SAM_USER_INFO_7 *id7, SAM_ACCOUNT *pwd)
|
||||
{
|
||||
fstring new_name;
|
||||
SAM_ACCOUNT *check_acct = NULL;
|
||||
NTSTATUS rc;
|
||||
BOOL check_rc;
|
||||
|
||||
if (id7 == NULL) {
|
||||
DEBUG(5, ("set_user_info_7: NULL id7\n"));
|
||||
@@ -2842,13 +2863,9 @@ static NTSTATUS set_user_info_7(const SAM_USER_INFO_7 *id7, SAM_ACCOUNT *pwd)
|
||||
simply that the rename fails with a slightly different status
|
||||
code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
|
||||
|
||||
pdb_init_sam(&check_acct);
|
||||
check_rc = pdb_getsampwnam(check_acct, new_name);
|
||||
pdb_free_sam(&check_acct);
|
||||
|
||||
if (check_rc == True) {
|
||||
/* this account exists: say so */
|
||||
return NT_STATUS_USER_EXISTS;
|
||||
rc = can_create(mem_ctx, new_name);
|
||||
if (!NT_STATUS_IS_OK(rc)) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = pdb_rename_sam_account(pwd, new_name);
|
||||
@@ -3365,7 +3382,8 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
|
||||
|
||||
switch (switch_value) {
|
||||
case 7:
|
||||
r_u->status = set_user_info_7(ctr->info.id7, pwd);
|
||||
r_u->status = set_user_info_7(p->mem_ctx,
|
||||
ctr->info.id7, pwd);
|
||||
break;
|
||||
case 16:
|
||||
if (!set_user_info_16(ctr->info.id16, pwd))
|
||||
@@ -4199,9 +4217,10 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
|
||||
|
||||
unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
|
||||
|
||||
/* check if group already exist */
|
||||
if ((grp=getgrnam(name)) != NULL)
|
||||
return NT_STATUS_GROUP_EXISTS;
|
||||
r_u->status = can_create(p->mem_ctx, name);
|
||||
if (!NT_STATUS_IS_OK(r_u->status)) {
|
||||
return r_u->status;
|
||||
}
|
||||
|
||||
se_priv_copy( &se_rights, &se_add_users );
|
||||
can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
|
||||
@@ -4289,6 +4308,11 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
|
||||
if (!sid_equal(&dom_sid, get_global_sam_sid()))
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
|
||||
r_u->status = can_create(p->mem_ctx, name);
|
||||
if (!NT_STATUS_IS_OK(r_u->status)) {
|
||||
return r_u->status;
|
||||
}
|
||||
|
||||
unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
|
||||
|
||||
se_priv_copy( &se_rights, &se_add_users );
|
||||
|
||||
@@ -1837,9 +1837,6 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
|
||||
gid_t *gids;
|
||||
size_t num_groups;
|
||||
size_t i;
|
||||
fstring grp_domain;
|
||||
fstring grp_name;
|
||||
enum SID_NAME_USE grp_type;
|
||||
struct passwd *passwd;
|
||||
NTSTATUS result;
|
||||
|
||||
@@ -1897,7 +1894,10 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
|
||||
|
||||
for (i=0; i<num_groups; i++) {
|
||||
|
||||
if ( lookup_sid(&sids[i], grp_domain, grp_name, &grp_type) ) {
|
||||
char *grp_name;
|
||||
|
||||
if ( lookup_sid(sampw->mem_ctx, &sids[i], NULL, &grp_name,
|
||||
NULL) ) {
|
||||
pstrcpy(p, grp_name);
|
||||
p += 21;
|
||||
count++;
|
||||
|
||||
Reference in New Issue
Block a user