1
0
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:
Volker Lendecke
2005-12-03 18:34:13 +00:00
committed by Gerald (Jerry) Carter
parent b9d1a65910
commit 9f99d04a54
19 changed files with 1001 additions and 616 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

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

View File

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

View File

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

View File

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