2004-11-27 00:24:36 +00:00
/*
Unix SMB / CIFS implementation .
mapping routines for SID < - > unix uid / gid
Copyright ( C ) Andrew Tridgell 2004
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
2007-07-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2004-11-27 00:24:36 +00:00
( 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
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-11-27 00:24:36 +00:00
*/
# include "includes.h"
2005-02-10 05:09:35 +00:00
# include "system/passwd.h"
2009-06-12 14:27:19 +02:00
# include "../libds/common/flags.h"
2005-12-28 15:38:36 +00:00
# include "dsdb/samdb/samdb.h"
# include "auth/auth.h"
2007-12-06 21:39:49 +01:00
# include "libcli/ldap/ldap_ndr.h"
2007-12-06 23:15:37 +01:00
# include "lib/ldb/include/ldb.h"
2008-10-11 21:31:42 +02:00
# include "../lib/util/util_ldb.h"
2006-04-02 12:02:01 +00:00
# include "libcli/security/security.h"
2007-12-02 17:09:52 +01:00
# include "param/param.h"
2004-11-29 03:21:46 +00:00
/*
these are used for the fallback local uid / gid to sid mapping
code .
*/
# define SIDMAP_LOCAL_USER_BASE 0x80000000
# define SIDMAP_LOCAL_GROUP_BASE 0xC0000000
# define SIDMAP_MAX_LOCAL_UID 0x3fffffff
# define SIDMAP_MAX_LOCAL_GID 0x3fffffff
2004-11-27 00:24:36 +00:00
/*
private context for sid mapping routines
*/
struct sidmap_context {
2006-04-29 17:34:49 +00:00
struct ldb_context * samctx ;
2004-11-27 00:24:36 +00:00
} ;
/*
open a sidmap context - use talloc_free to close
*/
2008-12-29 20:24:57 +01:00
struct sidmap_context * sidmap_open ( TALLOC_CTX * mem_ctx , struct tevent_context * ev_ctx ,
2008-04-17 12:23:44 +02:00
struct loadparm_context * lp_ctx )
2004-11-27 00:24:36 +00:00
{
struct sidmap_context * sidmap ;
2005-01-27 07:08:20 +00:00
sidmap = talloc ( mem_ctx , struct sidmap_context ) ;
2004-11-27 00:24:36 +00:00
if ( sidmap = = NULL ) {
return NULL ;
}
2008-04-17 12:23:44 +02:00
sidmap - > samctx = samdb_connect ( sidmap , ev_ctx , lp_ctx , system_session ( sidmap , lp_ctx ) ) ;
2004-11-27 00:24:36 +00:00
if ( sidmap - > samctx = = NULL ) {
talloc_free ( sidmap ) ;
return NULL ;
}
return sidmap ;
}
2004-11-29 03:21:46 +00:00
/*
check the sAMAccountType field of a search result to see if
the account is a user account
*/
2007-10-06 22:25:41 +00:00
static bool is_user_account ( struct ldb_message * res )
2004-11-29 03:21:46 +00:00
{
uint_t atype = samdb_result_uint ( res , " sAMAccountType " , 0 ) ;
if ( atype & & ( ! ( atype & ATYPE_ACCOUNT ) ) ) {
2007-10-06 22:25:41 +00:00
return false ;
2004-11-29 03:21:46 +00:00
}
2007-10-06 22:25:41 +00:00
return true ;
2004-11-29 03:21:46 +00:00
}
/*
check the sAMAccountType field of a search result to see if
the account is a group account
*/
2007-10-06 22:25:41 +00:00
static bool is_group_account ( struct ldb_message * res )
2004-11-29 03:21:46 +00:00
{
uint_t atype = samdb_result_uint ( res , " sAMAccountType " , 0 ) ;
if ( atype & & atype = = ATYPE_NORMAL_ACCOUNT ) {
2007-10-06 22:25:41 +00:00
return false ;
2004-11-29 03:21:46 +00:00
}
2007-10-06 22:25:41 +00:00
return true ;
2004-11-29 03:21:46 +00:00
}
/*
return the dom_sid of our primary domain
*/
static NTSTATUS sidmap_primary_domain_sid ( struct sidmap_context * sidmap ,
TALLOC_CTX * mem_ctx , struct dom_sid * * sid )
{
const char * attrs [ ] = { " objectSid " , NULL } ;
int ret ;
2005-06-24 00:18:20 +00:00
struct ldb_message * * res = NULL ;
2004-11-29 03:21:46 +00:00
2006-08-25 07:08:06 +00:00
ret = gendb_search_dn ( sidmap - > samctx , mem_ctx , NULL , & res , attrs ) ;
2004-11-29 03:21:46 +00:00
if ( ret ! = 1 ) {
2005-06-24 00:18:20 +00:00
talloc_free ( res ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_NO_SUCH_DOMAIN ;
}
2005-06-24 00:18:20 +00:00
* sid = samdb_result_dom_sid ( mem_ctx , res [ 0 ] , " objectSid " ) ;
talloc_free ( res ) ;
2004-11-29 03:21:46 +00:00
if ( * sid = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
return NT_STATUS_OK ;
}
2004-11-27 00:24:36 +00:00
/*
map a sid to a unix uid
*/
2008-04-02 04:53:27 +02:00
NTSTATUS sidmap_sid_to_unixuid ( struct sidmap_context * sidmap ,
2008-02-05 11:40:23 +01:00
const struct dom_sid * sid , uid_t * uid )
2004-11-27 00:24:36 +00:00
{
2008-02-05 11:40:23 +01:00
const char * attrs [ ] = { " sAMAccountName " , " uidNumber " ,
2006-08-31 13:07:51 +00:00
" sAMAccountType " , " unixName " , NULL } ;
2004-11-27 00:24:36 +00:00
int ret ;
const char * s ;
2006-02-01 10:04:11 +00:00
TALLOC_CTX * tmp_ctx ;
2004-11-27 00:24:36 +00:00
struct ldb_message * * res ;
2004-11-29 03:21:46 +00:00
struct dom_sid * domain_sid ;
NTSTATUS status ;
2004-11-27 00:24:36 +00:00
2006-02-01 10:04:11 +00:00
tmp_ctx = talloc_new ( sidmap ) ;
2004-11-27 00:24:36 +00:00
2008-02-05 11:40:23 +01:00
ret = gendb_search ( sidmap - > samctx , tmp_ctx , NULL , & res , attrs ,
" objectSid=%s " ,
ldap_encode_ndr_dom_sid ( tmp_ctx , sid ) ) ;
2004-11-27 00:24:36 +00:00
if ( ret ! = 1 ) {
2004-11-29 03:21:46 +00:00
goto allocated_sid ;
2004-11-27 00:24:36 +00:00
}
/* make sure its a user, not a group */
2004-11-29 03:21:46 +00:00
if ( ! is_user_account ( res [ 0 ] ) ) {
2008-02-05 11:40:23 +01:00
DEBUG ( 0 , ( " sid_to_unixuid: sid %s is not an account! \n " ,
2006-02-01 10:04:11 +00:00
dom_sid_string ( tmp_ctx , sid ) ) ) ;
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_INVALID_SID ;
2004-11-27 00:24:36 +00:00
}
/* first try to get the uid directly */
2006-08-12 15:22:03 +00:00
s = samdb_result_string ( res [ 0 ] , " uidNumber " , NULL ) ;
2004-11-27 00:24:36 +00:00
if ( s ! = NULL ) {
* uid = strtoul ( s , NULL , 0 ) ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-27 00:24:36 +00:00
return NT_STATUS_OK ;
}
/* next try via the UnixName attribute */
s = samdb_result_string ( res [ 0 ] , " unixName " , NULL ) ;
if ( s ! = NULL ) {
struct passwd * pwd = getpwnam ( s ) ;
if ( ! pwd ) {
2006-02-01 10:04:11 +00:00
DEBUG ( 0 , ( " unixName %s for sid %s does not exist as a local user \n " , s ,
dom_sid_string ( tmp_ctx , sid ) ) ) ;
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_NO_SUCH_USER ;
2004-11-27 00:24:36 +00:00
}
* uid = pwd - > pw_uid ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-27 00:24:36 +00:00
return NT_STATUS_OK ;
}
/* finally try via the sAMAccountName attribute */
s = samdb_result_string ( res [ 0 ] , " sAMAccountName " , NULL ) ;
if ( s ! = NULL ) {
struct passwd * pwd = getpwnam ( s ) ;
if ( ! pwd ) {
2005-06-24 00:18:20 +00:00
DEBUG ( 0 , ( " sAMAccountName '%s' for sid %s does not exist as a local user \n " ,
2006-02-01 10:04:11 +00:00
s , dom_sid_string ( tmp_ctx , sid ) ) ) ;
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_NO_SUCH_USER ;
2004-11-27 00:24:36 +00:00
}
* uid = pwd - > pw_uid ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-27 00:24:36 +00:00
return NT_STATUS_OK ;
}
2004-11-29 03:21:46 +00:00
allocated_sid :
2006-02-01 10:04:11 +00:00
status = sidmap_primary_domain_sid ( sidmap , tmp_ctx , & domain_sid ) ;
2004-11-29 03:21:46 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_NO_SUCH_DOMAIN ;
}
if ( dom_sid_in_domain ( domain_sid , sid ) ) {
uint32_t rid = sid - > sub_auths [ sid - > num_auths - 1 ] ;
if ( rid > = SIDMAP_LOCAL_USER_BASE & &
rid < SIDMAP_LOCAL_GROUP_BASE ) {
* uid = rid - SIDMAP_LOCAL_USER_BASE ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_OK ;
}
}
2006-08-12 15:22:03 +00:00
DEBUG ( 0 , ( " sid_to_unixuid: no uidNumber, unixName or sAMAccountName for sid %s \n " ,
2006-02-01 10:04:11 +00:00
dom_sid_string ( tmp_ctx , sid ) ) ) ;
2004-11-27 00:24:36 +00:00
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2007-04-12 12:38:32 +00:00
return NT_STATUS_NONE_MAPPED ;
2004-11-27 00:24:36 +00:00
}
2006-10-21 09:46:12 +00:00
/*
see if a sid is a group - very inefficient !
*/
2008-04-02 04:53:27 +02:00
bool sidmap_sid_is_group ( struct sidmap_context * sidmap , struct dom_sid * sid )
2006-10-21 09:46:12 +00:00
{
const char * attrs [ ] = { " sAMAccountType " , NULL } ;
int ret ;
TALLOC_CTX * tmp_ctx ;
struct ldb_message * * res ;
NTSTATUS status ;
struct dom_sid * domain_sid ;
2007-10-06 22:25:41 +00:00
bool is_group ;
2006-10-21 09:46:12 +00:00
tmp_ctx = talloc_new ( sidmap ) ;
ret = gendb_search ( sidmap - > samctx , tmp_ctx , NULL , & res , attrs ,
" objectSid=%s " , ldap_encode_ndr_dom_sid ( tmp_ctx , sid ) ) ;
if ( ret = = 1 ) {
is_group = is_group_account ( res [ 0 ] ) ;
talloc_free ( tmp_ctx ) ;
return is_group ;
}
status = sidmap_primary_domain_sid ( sidmap , tmp_ctx , & domain_sid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( tmp_ctx ) ;
2007-10-06 22:25:41 +00:00
return false ;
2006-10-21 09:46:12 +00:00
}
if ( dom_sid_in_domain ( domain_sid , sid ) ) {
uint32_t rid = sid - > sub_auths [ sid - > num_auths - 1 ] ;
if ( rid > = SIDMAP_LOCAL_GROUP_BASE ) {
talloc_free ( tmp_ctx ) ;
2007-10-06 22:25:41 +00:00
return true ;
2006-10-21 09:46:12 +00:00
}
}
talloc_free ( tmp_ctx ) ;
2007-10-06 22:25:41 +00:00
return false ;
2006-10-21 09:46:12 +00:00
}
2004-11-27 00:24:36 +00:00
/*
map a sid to a unix gid
*/
2008-04-02 04:53:27 +02:00
NTSTATUS sidmap_sid_to_unixgid ( struct sidmap_context * sidmap ,
2008-02-05 11:40:23 +01:00
const struct dom_sid * sid , gid_t * gid )
2004-11-27 00:24:36 +00:00
{
2008-02-05 11:40:23 +01:00
const char * attrs [ ] = { " sAMAccountName " , " gidNumber " ,
2004-11-27 00:24:36 +00:00
" unixName " , " sAMAccountType " , NULL } ;
int ret ;
const char * s ;
2006-02-01 10:04:11 +00:00
TALLOC_CTX * tmp_ctx ;
2004-11-27 00:24:36 +00:00
struct ldb_message * * res ;
2004-11-29 03:21:46 +00:00
NTSTATUS status ;
struct dom_sid * domain_sid ;
2004-11-27 00:24:36 +00:00
2006-02-01 10:04:11 +00:00
tmp_ctx = talloc_new ( sidmap ) ;
2004-11-27 00:24:36 +00:00
2006-08-25 07:08:06 +00:00
ret = gendb_search ( sidmap - > samctx , tmp_ctx , NULL , & res , attrs ,
2006-02-01 10:04:11 +00:00
" objectSid=%s " , ldap_encode_ndr_dom_sid ( tmp_ctx , sid ) ) ;
2004-11-27 00:24:36 +00:00
if ( ret ! = 1 ) {
2004-11-29 03:21:46 +00:00
goto allocated_sid ;
2004-11-27 00:24:36 +00:00
}
/* make sure its not a user */
2004-11-29 03:21:46 +00:00
if ( ! is_group_account ( res [ 0 ] ) ) {
2005-06-24 00:18:20 +00:00
DEBUG ( 0 , ( " sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT \n " ,
2006-02-01 10:04:11 +00:00
dom_sid_string ( tmp_ctx , sid ) ) ) ;
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_INVALID_SID ;
2004-11-27 00:24:36 +00:00
}
/* first try to get the gid directly */
2006-08-12 15:22:03 +00:00
s = samdb_result_string ( res [ 0 ] , " gidNumber " , NULL ) ;
2004-11-27 00:24:36 +00:00
if ( s ! = NULL ) {
* gid = strtoul ( s , NULL , 0 ) ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-27 00:24:36 +00:00
return NT_STATUS_OK ;
}
/* next try via the UnixName attribute */
s = samdb_result_string ( res [ 0 ] , " unixName " , NULL ) ;
if ( s ! = NULL ) {
struct group * grp = getgrnam ( s ) ;
if ( ! grp ) {
DEBUG ( 0 , ( " unixName '%s' for sid %s does not exist as a local group \n " ,
2006-02-01 10:04:11 +00:00
s , dom_sid_string ( tmp_ctx , sid ) ) ) ;
talloc_free ( tmp_ctx ) ;
2006-04-13 12:13:40 +00:00
return NT_STATUS_NO_SUCH_GROUP ;
2004-11-27 00:24:36 +00:00
}
* gid = grp - > gr_gid ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-27 00:24:36 +00:00
return NT_STATUS_OK ;
}
/* finally try via the sAMAccountName attribute */
s = samdb_result_string ( res [ 0 ] , " sAMAccountName " , NULL ) ;
if ( s ! = NULL ) {
struct group * grp = getgrnam ( s ) ;
if ( ! grp ) {
2006-02-01 10:04:11 +00:00
DEBUG ( 0 , ( " sAMAccountName '%s' for sid %s does not exist as a local group \n " , s , dom_sid_string ( tmp_ctx , sid ) ) ) ;
talloc_free ( tmp_ctx ) ;
2006-04-13 12:13:40 +00:00
return NT_STATUS_NO_SUCH_GROUP ;
2004-11-27 00:24:36 +00:00
}
* gid = grp - > gr_gid ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-27 00:24:36 +00:00
return NT_STATUS_OK ;
}
2004-11-29 03:21:46 +00:00
allocated_sid :
2006-02-01 10:04:11 +00:00
status = sidmap_primary_domain_sid ( sidmap , tmp_ctx , & domain_sid ) ;
2004-11-29 03:21:46 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_NO_SUCH_DOMAIN ;
}
if ( dom_sid_in_domain ( domain_sid , sid ) ) {
uint32_t rid = sid - > sub_auths [ sid - > num_auths - 1 ] ;
if ( rid > = SIDMAP_LOCAL_GROUP_BASE ) {
* gid = rid - SIDMAP_LOCAL_GROUP_BASE ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_OK ;
}
}
2006-08-12 15:22:03 +00:00
DEBUG ( 0 , ( " sid_to_unixgid: no gidNumber, unixName or sAMAccountName for sid %s \n " ,
2006-02-01 10:04:11 +00:00
dom_sid_string ( tmp_ctx , sid ) ) ) ;
2004-11-27 00:24:36 +00:00
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2007-04-12 12:38:32 +00:00
return NT_STATUS_NONE_MAPPED ;
2004-11-29 03:21:46 +00:00
}
/*
map a unix uid to a dom_sid
the returned sid is allocated in the supplied mem_ctx
*/
2008-04-02 04:53:27 +02:00
NTSTATUS sidmap_uid_to_sid ( struct sidmap_context * sidmap ,
2006-04-07 13:15:46 +00:00
TALLOC_CTX * mem_ctx ,
2008-02-05 11:40:23 +01:00
const uid_t uid , struct dom_sid * * sid )
2004-11-29 03:21:46 +00:00
{
const char * attrs [ ] = { " sAMAccountName " , " objectSid " , " sAMAccountType " , NULL } ;
int ret , i ;
2006-02-01 10:04:11 +00:00
TALLOC_CTX * tmp_ctx ;
2004-11-29 03:21:46 +00:00
struct ldb_message * * res ;
struct passwd * pwd ;
struct dom_sid * domain_sid ;
NTSTATUS status ;
/*
we search for the mapping in the following order :
- check if the uid is in the dynamic uid range assigned for winbindd
use . If it is , then look in winbindd sid mapping
database ( not implemented yet )
2006-08-12 15:22:03 +00:00
- look for a user account in samdb that has uidNumber set to the
2004-11-29 03:21:46 +00:00
given uid
- look for a user account in samdb that has unixName or
sAMAccountName set to the name given by getpwuid ( )
- assign a SID by adding the uid to SIDMAP_LOCAL_USER_BASE in the local
domain
*/
2006-02-01 10:04:11 +00:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2004-11-29 03:21:46 +00:00
/*
2006-08-12 15:22:03 +00:00
step 2 : look for a user account in samdb that has uidNumber set to the
2004-11-29 03:21:46 +00:00
given uid
*/
2006-08-25 07:08:06 +00:00
ret = gendb_search ( sidmap - > samctx , tmp_ctx , NULL , & res , attrs ,
2006-08-12 15:22:03 +00:00
" uidNumber=%u " , ( unsigned int ) uid ) ;
2004-11-29 03:21:46 +00:00
for ( i = 0 ; i < ret ; i + + ) {
if ( ! is_user_account ( res [ i ] ) ) continue ;
2005-06-24 00:18:20 +00:00
* sid = samdb_result_dom_sid ( mem_ctx , res [ i ] , " objectSid " ) ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2005-06-24 00:18:20 +00:00
NT_STATUS_HAVE_NO_MEMORY ( * sid ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_OK ;
}
/*
step 3 : look for a user account in samdb that has unixName
or sAMAccountName set to the name given by getpwuid ( )
*/
pwd = getpwuid ( uid ) ;
if ( pwd = = NULL ) {
goto allocate_sid ;
}
2006-02-01 10:04:11 +00:00
ret = gendb_search ( sidmap - > samctx , tmp_ctx , NULL , & res , attrs ,
2004-11-29 03:21:46 +00:00
" (|(unixName=%s)(sAMAccountName=%s)) " ,
pwd - > pw_name , pwd - > pw_name ) ;
for ( i = 0 ; i < ret ; i + + ) {
if ( ! is_user_account ( res [ i ] ) ) continue ;
2005-06-24 00:18:20 +00:00
* sid = samdb_result_dom_sid ( mem_ctx , res [ i ] , " objectSid " ) ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2005-06-24 00:18:20 +00:00
NT_STATUS_HAVE_NO_MEMORY ( * sid ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_OK ;
}
/*
step 4 : assign a SID by adding the uid to
SIDMAP_LOCAL_USER_BASE in the local domain
*/
allocate_sid :
if ( uid > SIDMAP_MAX_LOCAL_UID ) {
2007-04-12 12:38:32 +00:00
return NT_STATUS_NONE_MAPPED ;
2004-11-29 03:21:46 +00:00
}
2006-02-01 10:04:11 +00:00
status = sidmap_primary_domain_sid ( sidmap , tmp_ctx , & domain_sid ) ;
2004-11-29 03:21:46 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
return status ;
}
* sid = dom_sid_add_rid ( mem_ctx , domain_sid , SIDMAP_LOCAL_USER_BASE + uid ) ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
if ( * sid = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
return NT_STATUS_OK ;
}
/*
map a unix gid to a dom_sid
the returned sid is allocated in the supplied mem_ctx
*/
2008-04-02 04:53:27 +02:00
NTSTATUS sidmap_gid_to_sid ( struct sidmap_context * sidmap ,
2006-04-07 13:15:46 +00:00
TALLOC_CTX * mem_ctx ,
2008-02-05 11:40:23 +01:00
const gid_t gid , struct dom_sid * * sid )
2004-11-29 03:21:46 +00:00
{
const char * attrs [ ] = { " sAMAccountName " , " objectSid " , " sAMAccountType " , NULL } ;
int ret , i ;
2006-02-01 10:04:11 +00:00
TALLOC_CTX * tmp_ctx ;
2004-11-29 03:21:46 +00:00
struct ldb_message * * res ;
struct group * grp ;
struct dom_sid * domain_sid ;
NTSTATUS status ;
/*
we search for the mapping in the following order :
- check if the gid is in the dynamic gid range assigned for winbindd
use . If it is , then look in winbindd sid mapping
database ( not implemented yet )
2006-08-12 15:22:03 +00:00
- look for a group account in samdb that has gidNumber set to the
2004-11-29 03:21:46 +00:00
given gid
- look for a group account in samdb that has unixName or
sAMAccountName set to the name given by getgrgid ( )
- assign a SID by adding the gid to SIDMAP_LOCAL_GROUP_BASE in the local
domain
*/
2006-02-01 10:04:11 +00:00
tmp_ctx = talloc_new ( sidmap ) ;
2004-11-29 03:21:46 +00:00
/*
2006-08-12 15:22:03 +00:00
step 2 : look for a group account in samdb that has gidNumber set to the
2004-11-29 03:21:46 +00:00
given gid
*/
2006-08-25 07:08:06 +00:00
ret = gendb_search ( sidmap - > samctx , tmp_ctx , NULL , & res , attrs ,
2006-08-12 15:22:03 +00:00
" gidNumber=%u " , ( unsigned int ) gid ) ;
2004-11-29 03:21:46 +00:00
for ( i = 0 ; i < ret ; i + + ) {
if ( ! is_group_account ( res [ i ] ) ) continue ;
2005-06-24 00:18:20 +00:00
* sid = samdb_result_dom_sid ( mem_ctx , res [ i ] , " objectSid " ) ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2005-06-24 00:18:20 +00:00
NT_STATUS_HAVE_NO_MEMORY ( * sid ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_OK ;
}
/*
step 3 : look for a group account in samdb that has unixName
or sAMAccountName set to the name given by getgrgid ( )
*/
grp = getgrgid ( gid ) ;
if ( grp = = NULL ) {
goto allocate_sid ;
}
2006-08-25 07:08:06 +00:00
ret = gendb_search ( sidmap - > samctx , tmp_ctx , NULL , & res , attrs ,
2004-11-29 03:21:46 +00:00
" (|(unixName=%s)(sAMAccountName=%s)) " ,
grp - > gr_name , grp - > gr_name ) ;
for ( i = 0 ; i < ret ; i + + ) {
if ( ! is_group_account ( res [ i ] ) ) continue ;
2005-06-24 00:18:20 +00:00
* sid = samdb_result_dom_sid ( mem_ctx , res [ i ] , " objectSid " ) ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2005-06-24 00:18:20 +00:00
NT_STATUS_HAVE_NO_MEMORY ( * sid ) ;
2004-11-29 03:21:46 +00:00
return NT_STATUS_OK ;
}
/*
step 4 : assign a SID by adding the gid to
SIDMAP_LOCAL_GROUP_BASE in the local domain
*/
allocate_sid :
if ( gid > SIDMAP_MAX_LOCAL_GID ) {
2007-04-12 12:38:32 +00:00
return NT_STATUS_NONE_MAPPED ;
2004-11-29 03:21:46 +00:00
}
2006-02-01 10:04:11 +00:00
status = sidmap_primary_domain_sid ( sidmap , tmp_ctx , & domain_sid ) ;
2004-11-29 03:21:46 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
return status ;
}
* sid = dom_sid_add_rid ( mem_ctx , domain_sid , SIDMAP_LOCAL_GROUP_BASE + gid ) ;
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-29 03:21:46 +00:00
if ( * sid = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
return NT_STATUS_OK ;
2004-11-27 00:24:36 +00:00
}
2004-11-29 04:24:50 +00:00
/*
check if a sid is in the range of auto - allocated SIDs from our primary domain ,
and if it is , then return the name and atype
*/
2008-04-02 04:53:27 +02:00
NTSTATUS sidmap_allocated_sid_lookup ( struct sidmap_context * sidmap ,
2006-04-07 13:15:46 +00:00
TALLOC_CTX * mem_ctx ,
const struct dom_sid * sid ,
const char * * name ,
2007-09-17 05:31:49 +00:00
enum lsa_SidType * rtype )
2004-11-29 04:24:50 +00:00
{
NTSTATUS status ;
struct dom_sid * domain_sid ;
2006-02-01 10:04:11 +00:00
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
2007-09-17 05:31:49 +00:00
uint32_t rid , atype ;
2006-02-01 10:04:11 +00:00
status = sidmap_primary_domain_sid ( sidmap , tmp_ctx , & domain_sid ) ;
2004-11-29 04:24:50 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
if ( ! dom_sid_in_domain ( domain_sid , sid ) ) {
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2007-04-12 12:38:32 +00:00
return NT_STATUS_NONE_MAPPED ;
2004-11-29 04:24:50 +00:00
}
2006-02-01 10:04:11 +00:00
talloc_free ( tmp_ctx ) ;
2004-11-29 04:24:50 +00:00
rid = sid - > sub_auths [ sid - > num_auths - 1 ] ;
if ( rid < SIDMAP_LOCAL_USER_BASE ) {
2007-04-12 12:38:32 +00:00
return NT_STATUS_NONE_MAPPED ;
2004-11-29 04:24:50 +00:00
}
if ( rid < SIDMAP_LOCAL_GROUP_BASE ) {
struct passwd * pwd ;
uid_t uid = rid - SIDMAP_LOCAL_USER_BASE ;
2007-09-17 05:31:49 +00:00
atype = ATYPE_NORMAL_ACCOUNT ;
* rtype = samdb_atype_map ( atype ) ;
2004-11-29 04:24:50 +00:00
pwd = getpwuid ( uid ) ;
if ( pwd = = NULL ) {
* name = talloc_asprintf ( mem_ctx , " uid%u " , uid ) ;
} else {
* name = talloc_strdup ( mem_ctx , pwd - > pw_name ) ;
}
} else {
struct group * grp ;
gid_t gid = rid - SIDMAP_LOCAL_GROUP_BASE ;
2007-09-17 05:31:49 +00:00
atype = ATYPE_LOCAL_GROUP ;
* rtype = samdb_atype_map ( atype ) ;
2004-11-29 04:24:50 +00:00
grp = getgrgid ( gid ) ;
if ( grp = = NULL ) {
* name = talloc_asprintf ( mem_ctx , " gid%u " , gid ) ;
} else {
* name = talloc_strdup ( mem_ctx , grp - > gr_name ) ;
}
}
if ( * name = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
return NT_STATUS_OK ;
}