2008-06-16 14:37:57 +04:00
/*
Unix SMB / CIFS implementation .
dump the remote SAM using rpc samsync operations
Copyright ( C ) Andrew Tridgell 2002
Copyright ( C ) Tim Potter 2001 , 2002
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2005
Modified by Volker Lendecke 2002
Copyright ( C ) Jeremy Allison 2005.
Copyright ( C ) Guenther Deschner 2008.
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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2008-06-17 23:42:27 +04:00
# include "libnet/libnet_samsync.h"
2008-06-16 14:37:57 +04:00
/* uid's and gid's for writing deltas to ldif */
static uint32 ldif_gid = 999 ;
static uint32 ldif_uid = 999 ;
/* Structure for mapping accounts to groups */
/* Array element is the group rid */
typedef struct _groupmap {
uint32_t rid ;
uint32_t gidNumber ;
const char * sambaSID ;
const char * group_dn ;
} GROUPMAP ;
typedef struct _accountmap {
uint32_t rid ;
const char * cn ;
} ACCOUNTMAP ;
struct samsync_ldif_context {
GROUPMAP * groupmap ;
ACCOUNTMAP * accountmap ;
bool initialized ;
const char * add_template ;
const char * mod_template ;
char * add_name ;
char * mod_name ;
FILE * add_file ;
FILE * mod_file ;
FILE * ldif_file ;
const char * suffix ;
int num_alloced ;
} ;
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS populate_ldap_for_ldif ( const char * sid ,
const char * suffix ,
const char * builtin_sid ,
FILE * add_fd )
{
const char * user_suffix , * group_suffix , * machine_suffix , * idmap_suffix ;
char * user_attr = NULL , * group_attr = NULL ;
char * suffix_attr ;
int len ;
/* Get the suffix attribute */
suffix_attr = sstring_sub ( suffix , ' = ' , ' , ' ) ;
if ( suffix_attr = = NULL ) {
len = strlen ( suffix ) ;
suffix_attr = ( char * ) SMB_MALLOC ( len + 1 ) ;
memcpy ( suffix_attr , suffix , len ) ;
suffix_attr [ len ] = ' \0 ' ;
}
/* Write the base */
fprintf ( add_fd , " # %s \n " , suffix ) ;
fprintf ( add_fd , " dn: %s \n " , suffix ) ;
fprintf ( add_fd , " objectClass: dcObject \n " ) ;
fprintf ( add_fd , " objectClass: organization \n " ) ;
fprintf ( add_fd , " o: %s \n " , suffix_attr ) ;
fprintf ( add_fd , " dc: %s \n " , suffix_attr ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
user_suffix = lp_ldap_user_suffix ( ) ;
if ( user_suffix = = NULL ) {
SAFE_FREE ( suffix_attr ) ;
return NT_STATUS_NO_MEMORY ;
}
/* If it exists and is distinct from other containers,
Write the Users entity */
if ( * user_suffix & & strcmp ( user_suffix , suffix ) ) {
user_attr = sstring_sub ( lp_ldap_user_suffix ( ) , ' = ' , ' , ' ) ;
fprintf ( add_fd , " # %s \n " , user_suffix ) ;
fprintf ( add_fd , " dn: %s \n " , user_suffix ) ;
fprintf ( add_fd , " objectClass: organizationalUnit \n " ) ;
fprintf ( add_fd , " ou: %s \n " , user_attr ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
}
group_suffix = lp_ldap_group_suffix ( ) ;
if ( group_suffix = = NULL ) {
SAFE_FREE ( suffix_attr ) ;
SAFE_FREE ( user_attr ) ;
return NT_STATUS_NO_MEMORY ;
}
/* If it exists and is distinct from other containers,
Write the Groups entity */
if ( * group_suffix & & strcmp ( group_suffix , suffix ) ) {
group_attr = sstring_sub ( lp_ldap_group_suffix ( ) , ' = ' , ' , ' ) ;
fprintf ( add_fd , " # %s \n " , group_suffix ) ;
fprintf ( add_fd , " dn: %s \n " , group_suffix ) ;
fprintf ( add_fd , " objectClass: organizationalUnit \n " ) ;
fprintf ( add_fd , " ou: %s \n " , group_attr ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
}
/* If it exists and is distinct from other containers,
Write the Computers entity */
machine_suffix = lp_ldap_machine_suffix ( ) ;
if ( machine_suffix = = NULL ) {
SAFE_FREE ( suffix_attr ) ;
SAFE_FREE ( user_attr ) ;
SAFE_FREE ( group_attr ) ;
return NT_STATUS_NO_MEMORY ;
}
if ( * machine_suffix & & strcmp ( machine_suffix , user_suffix ) & &
strcmp ( machine_suffix , suffix ) ) {
char * machine_ou = NULL ;
fprintf ( add_fd , " # %s \n " , machine_suffix ) ;
fprintf ( add_fd , " dn: %s \n " , machine_suffix ) ;
fprintf ( add_fd , " objectClass: organizationalUnit \n " ) ;
/* this isn't totally correct as it assumes that
there _must_ be an ou . just fixing memleak now . jmcd */
machine_ou = sstring_sub ( lp_ldap_machine_suffix ( ) , ' = ' , ' , ' ) ;
fprintf ( add_fd , " ou: %s \n " , machine_ou ) ;
SAFE_FREE ( machine_ou ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
}
/* If it exists and is distinct from other containers,
Write the IdMap entity */
idmap_suffix = lp_ldap_idmap_suffix ( ) ;
if ( idmap_suffix = = NULL ) {
SAFE_FREE ( suffix_attr ) ;
SAFE_FREE ( user_attr ) ;
SAFE_FREE ( group_attr ) ;
return NT_STATUS_NO_MEMORY ;
}
if ( * idmap_suffix & &
strcmp ( idmap_suffix , user_suffix ) & &
strcmp ( idmap_suffix , suffix ) ) {
char * s ;
fprintf ( add_fd , " # %s \n " , idmap_suffix ) ;
fprintf ( add_fd , " dn: %s \n " , idmap_suffix ) ;
fprintf ( add_fd , " ObjectClass: organizationalUnit \n " ) ;
s = sstring_sub ( lp_ldap_idmap_suffix ( ) , ' = ' , ' , ' ) ;
fprintf ( add_fd , " ou: %s \n " , s ) ;
SAFE_FREE ( s ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
}
/* Write the domain entity */
fprintf ( add_fd , " # %s, %s \n " , lp_workgroup ( ) , suffix ) ;
fprintf ( add_fd , " dn: sambaDomainName=%s,%s \n " , lp_workgroup ( ) ,
suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_DOMINFO ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_IDPOOL ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " sambaDomainName: %s \n " , lp_workgroup ( ) ) ;
fprintf ( add_fd , " sambaSID: %s \n " , sid ) ;
fprintf ( add_fd , " uidNumber: %d \n " , + + ldif_uid ) ;
fprintf ( add_fd , " gidNumber: %d \n " , + + ldif_gid ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Domain Admins entity */
fprintf ( add_fd , " # Domain Admins, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Domain Admins,ou=%s,%s \n " , group_attr ,
suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXGROUP ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_GROUPMAP ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " cn: Domain Admins \n " ) ;
fprintf ( add_fd , " memberUid: Administrator \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Administrators \n " ) ;
fprintf ( add_fd , " gidNumber: 512 \n " ) ;
fprintf ( add_fd , " sambaSID: %s-512 \n " , sid ) ;
fprintf ( add_fd , " sambaGroupType: 2 \n " ) ;
fprintf ( add_fd , " displayName: Domain Admins \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Domain Users entity */
fprintf ( add_fd , " # Domain Users, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Domain Users,ou=%s,%s \n " , group_attr ,
suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXGROUP ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_GROUPMAP ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " cn: Domain Users \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Users \n " ) ;
fprintf ( add_fd , " gidNumber: 513 \n " ) ;
fprintf ( add_fd , " sambaSID: %s-513 \n " , sid ) ;
fprintf ( add_fd , " sambaGroupType: 2 \n " ) ;
fprintf ( add_fd , " displayName: Domain Users \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Domain Guests entity */
fprintf ( add_fd , " # Domain Guests, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Domain Guests,ou=%s,%s \n " , group_attr ,
suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXGROUP ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_GROUPMAP ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " cn: Domain Guests \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Guests \n " ) ;
fprintf ( add_fd , " gidNumber: 514 \n " ) ;
fprintf ( add_fd , " sambaSID: %s-514 \n " , sid ) ;
fprintf ( add_fd , " sambaGroupType: 2 \n " ) ;
fprintf ( add_fd , " displayName: Domain Guests \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Domain Computers entity */
fprintf ( add_fd , " # Domain Computers, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Domain Computers,ou=%s,%s \n " ,
group_attr , suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXGROUP ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_GROUPMAP ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " gidNumber: 515 \n " ) ;
fprintf ( add_fd , " cn: Domain Computers \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Computers accounts \n " ) ;
fprintf ( add_fd , " sambaSID: %s-515 \n " , sid ) ;
fprintf ( add_fd , " sambaGroupType: 2 \n " ) ;
fprintf ( add_fd , " displayName: Domain Computers \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Admininistrators Groups entity */
fprintf ( add_fd , " # Administrators, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Administrators,ou=%s,%s \n " , group_attr ,
suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXGROUP ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_GROUPMAP ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " gidNumber: 544 \n " ) ;
fprintf ( add_fd , " cn: Administrators \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Members can fully administer the computer/sambaDomainName \n " ) ;
fprintf ( add_fd , " sambaSID: %s-544 \n " , builtin_sid ) ;
fprintf ( add_fd , " sambaGroupType: 5 \n " ) ;
fprintf ( add_fd , " displayName: Administrators \n " ) ;
fprintf ( add_fd , " \n " ) ;
/* Write the Print Operator entity */
fprintf ( add_fd , " # Print Operators, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Print Operators,ou=%s,%s \n " ,
group_attr , suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXGROUP ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_GROUPMAP ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " gidNumber: 550 \n " ) ;
fprintf ( add_fd , " cn: Print Operators \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Print Operators \n " ) ;
fprintf ( add_fd , " sambaSID: %s-550 \n " , builtin_sid ) ;
fprintf ( add_fd , " sambaGroupType: 5 \n " ) ;
fprintf ( add_fd , " displayName: Print Operators \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Backup Operators entity */
fprintf ( add_fd , " # Backup Operators, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Backup Operators,ou=%s,%s \n " ,
group_attr , suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXGROUP ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_GROUPMAP ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " gidNumber: 551 \n " ) ;
fprintf ( add_fd , " cn: Backup Operators \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Members can bypass file security to back up files \n " ) ;
fprintf ( add_fd , " sambaSID: %s-551 \n " , builtin_sid ) ;
fprintf ( add_fd , " sambaGroupType: 5 \n " ) ;
fprintf ( add_fd , " displayName: Backup Operators \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Replicators entity */
fprintf ( add_fd , " # Replicators, %s, %s \n " , group_attr , suffix ) ;
fprintf ( add_fd , " dn: cn=Replicators,ou=%s,%s \n " , group_attr ,
suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXGROUP ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_GROUPMAP ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " gidNumber: 552 \n " ) ;
fprintf ( add_fd , " cn: Replicators \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Supports file replication in a sambaDomainName \n " ) ;
fprintf ( add_fd , " sambaSID: %s-552 \n " , builtin_sid ) ;
fprintf ( add_fd , " sambaGroupType: 5 \n " ) ;
fprintf ( add_fd , " displayName: Replicators \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Deallocate memory, and return */
SAFE_FREE ( suffix_attr ) ;
SAFE_FREE ( user_attr ) ;
SAFE_FREE ( group_attr ) ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS map_populate_groups ( TALLOC_CTX * mem_ctx ,
GROUPMAP * groupmap ,
ACCOUNTMAP * accountmap ,
const char * sid ,
const char * suffix ,
const char * builtin_sid )
{
char * group_attr = sstring_sub ( lp_ldap_group_suffix ( ) , ' = ' , ' , ' ) ;
/* Map the groups created by populate_ldap_for_ldif */
groupmap [ 0 ] . rid = 512 ;
groupmap [ 0 ] . gidNumber = 512 ;
groupmap [ 0 ] . sambaSID = talloc_asprintf ( mem_ctx , " %s-512 " , sid ) ;
groupmap [ 0 ] . group_dn = talloc_asprintf ( mem_ctx ,
" cn=Domain Admins,ou=%s,%s " , group_attr , suffix ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 0 ] . sambaSID ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 0 ] . group_dn ) ;
accountmap [ 0 ] . rid = 512 ;
accountmap [ 0 ] . cn = talloc_strdup ( mem_ctx , " Domain Admins " ) ;
NT_STATUS_HAVE_NO_MEMORY ( accountmap [ 0 ] . cn ) ;
groupmap [ 1 ] . rid = 513 ;
groupmap [ 1 ] . gidNumber = 513 ;
groupmap [ 1 ] . sambaSID = talloc_asprintf ( mem_ctx , " %s-513 " , sid ) ;
groupmap [ 1 ] . group_dn = talloc_asprintf ( mem_ctx ,
" cn=Domain Users,ou=%s,%s " , group_attr , suffix ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 1 ] . sambaSID ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 1 ] . group_dn ) ;
accountmap [ 1 ] . rid = 513 ;
accountmap [ 1 ] . cn = talloc_strdup ( mem_ctx , " Domain Users " ) ;
NT_STATUS_HAVE_NO_MEMORY ( accountmap [ 1 ] . cn ) ;
groupmap [ 2 ] . rid = 514 ;
groupmap [ 2 ] . gidNumber = 514 ;
groupmap [ 2 ] . sambaSID = talloc_asprintf ( mem_ctx , " %s-514 " , sid ) ;
groupmap [ 2 ] . group_dn = talloc_asprintf ( mem_ctx ,
" cn=Domain Guests,ou=%s,%s " , group_attr , suffix ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 2 ] . sambaSID ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 2 ] . group_dn ) ;
accountmap [ 2 ] . rid = 514 ;
accountmap [ 2 ] . cn = talloc_strdup ( mem_ctx , " Domain Guests " ) ;
NT_STATUS_HAVE_NO_MEMORY ( accountmap [ 2 ] . cn ) ;
groupmap [ 3 ] . rid = 515 ;
groupmap [ 3 ] . gidNumber = 515 ;
groupmap [ 3 ] . sambaSID = talloc_asprintf ( mem_ctx , " %s-515 " , sid ) ;
groupmap [ 3 ] . group_dn = talloc_asprintf ( mem_ctx ,
" cn=Domain Computers,ou=%s,%s " , group_attr , suffix ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 3 ] . sambaSID ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 3 ] . group_dn ) ;
accountmap [ 3 ] . rid = 515 ;
accountmap [ 3 ] . cn = talloc_strdup ( mem_ctx , " Domain Computers " ) ;
NT_STATUS_HAVE_NO_MEMORY ( accountmap [ 3 ] . cn ) ;
groupmap [ 4 ] . rid = 544 ;
groupmap [ 4 ] . gidNumber = 544 ;
groupmap [ 4 ] . sambaSID = talloc_asprintf ( mem_ctx , " %s-544 " , builtin_sid ) ;
groupmap [ 4 ] . group_dn = talloc_asprintf ( mem_ctx ,
" cn=Administrators,ou=%s,%s " , group_attr , suffix ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 4 ] . sambaSID ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 4 ] . group_dn ) ;
accountmap [ 4 ] . rid = 515 ;
accountmap [ 4 ] . cn = talloc_strdup ( mem_ctx , " Administrators " ) ;
NT_STATUS_HAVE_NO_MEMORY ( accountmap [ 4 ] . cn ) ;
groupmap [ 5 ] . rid = 550 ;
groupmap [ 5 ] . gidNumber = 550 ;
groupmap [ 5 ] . sambaSID = talloc_asprintf ( mem_ctx , " %s-550 " , builtin_sid ) ;
groupmap [ 5 ] . group_dn = talloc_asprintf ( mem_ctx ,
" cn=Print Operators,ou=%s,%s " , group_attr , suffix ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 5 ] . sambaSID ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 5 ] . group_dn ) ;
accountmap [ 5 ] . rid = 550 ;
accountmap [ 5 ] . cn = talloc_strdup ( mem_ctx , " Print Operators " ) ;
NT_STATUS_HAVE_NO_MEMORY ( accountmap [ 5 ] . cn ) ;
groupmap [ 6 ] . rid = 551 ;
groupmap [ 6 ] . gidNumber = 551 ;
groupmap [ 6 ] . sambaSID = talloc_asprintf ( mem_ctx , " %s-551 " , builtin_sid ) ;
groupmap [ 6 ] . group_dn = talloc_asprintf ( mem_ctx ,
" cn=Backup Operators,ou=%s,%s " , group_attr , suffix ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 6 ] . sambaSID ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 6 ] . group_dn ) ;
accountmap [ 6 ] . rid = 551 ;
accountmap [ 6 ] . cn = talloc_strdup ( mem_ctx , " Backup Operators " ) ;
NT_STATUS_HAVE_NO_MEMORY ( accountmap [ 6 ] . cn ) ;
groupmap [ 7 ] . rid = 552 ;
groupmap [ 7 ] . gidNumber = 552 ;
groupmap [ 7 ] . sambaSID = talloc_asprintf ( mem_ctx , " %s-552 " , builtin_sid ) ;
groupmap [ 7 ] . group_dn = talloc_asprintf ( mem_ctx ,
" cn=Replicators,ou=%s,%s " , group_attr , suffix ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 7 ] . sambaSID ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap [ 7 ] . group_dn ) ;
accountmap [ 7 ] . rid = 551 ;
accountmap [ 7 ] . cn = talloc_strdup ( mem_ctx , " Replicators " ) ;
NT_STATUS_HAVE_NO_MEMORY ( accountmap [ 7 ] . cn ) ;
SAFE_FREE ( group_attr ) ;
return NT_STATUS_OK ;
}
/*
* This is a crap routine , but I think it ' s the quickest way to solve the
* UTF8 - > base64 problem .
*/
static int fprintf_attr ( FILE * add_fd , const char * attr_name ,
const char * fmt , . . . )
{
va_list ap ;
char * value , * p , * base64 ;
DATA_BLOB base64_blob ;
bool do_base64 = false ;
int res ;
va_start ( ap , fmt ) ;
value = talloc_vasprintf ( NULL , fmt , ap ) ;
va_end ( ap ) ;
SMB_ASSERT ( value ! = NULL ) ;
for ( p = value ; * p ; p + + ) {
if ( * p & 0x80 ) {
do_base64 = true ;
break ;
}
}
if ( ! do_base64 ) {
bool only_whitespace = true ;
for ( p = value ; * p ; p + + ) {
/*
* I know that this not multibyte safe , but we break
* on the first non - whitespace character anyway .
*/
if ( ! isspace ( * p ) ) {
only_whitespace = false ;
break ;
}
}
if ( only_whitespace ) {
do_base64 = true ;
}
}
if ( ! do_base64 ) {
res = fprintf ( add_fd , " %s: %s \n " , attr_name , value ) ;
TALLOC_FREE ( value ) ;
return res ;
}
base64_blob . data = ( unsigned char * ) value ;
base64_blob . length = strlen ( value ) ;
base64 = base64_encode_data_blob ( value , base64_blob ) ;
SMB_ASSERT ( base64 ! = NULL ) ;
res = fprintf ( add_fd , " %s:: %s \n " , attr_name , base64 ) ;
TALLOC_FREE ( value ) ;
return res ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS fetch_group_info_to_ldif ( TALLOC_CTX * mem_ctx ,
struct netr_DELTA_GROUP * r ,
GROUPMAP * groupmap ,
FILE * add_fd ,
const char * sid ,
const char * suffix )
{
const char * groupname = r - > group_name . string ;
uint32 grouptype = 0 , g_rid = 0 ;
char * group_attr = sstring_sub ( lp_ldap_group_suffix ( ) , ' = ' , ' , ' ) ;
/* Set up the group type (always 2 for group info) */
grouptype = 2 ;
/* These groups are entered by populate_ldap_for_ldif */
if ( strcmp ( groupname , " Domain Admins " ) = = 0 | |
strcmp ( groupname , " Domain Users " ) = = 0 | |
strcmp ( groupname , " Domain Guests " ) = = 0 | |
strcmp ( groupname , " Domain Computers " ) = = 0 | |
strcmp ( groupname , " Administrators " ) = = 0 | |
strcmp ( groupname , " Print Operators " ) = = 0 | |
strcmp ( groupname , " Backup Operators " ) = = 0 | |
strcmp ( groupname , " Replicators " ) = = 0 ) {
SAFE_FREE ( group_attr ) ;
return NT_STATUS_OK ;
} else {
/* Increment the gid for the new group */
ldif_gid + + ;
}
/* Map the group rid, gid, and dn */
g_rid = r - > rid ;
groupmap - > rid = g_rid ;
groupmap - > gidNumber = ldif_gid ;
groupmap - > sambaSID = talloc_asprintf ( mem_ctx , " %s-%d " , sid , g_rid ) ;
groupmap - > group_dn = talloc_asprintf ( mem_ctx ,
" cn=%s,ou=%s,%s " , groupname , group_attr , suffix ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap - > sambaSID ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap - > group_dn ) ;
/* Write the data to the temporary add ldif file */
fprintf ( add_fd , " # %s, %s, %s \n " , groupname , group_attr ,
suffix ) ;
fprintf_attr ( add_fd , " dn " , " cn=%s,ou=%s,%s " , groupname , group_attr ,
suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXGROUP ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_GROUPMAP ) ;
2008-06-16 14:37:57 +04:00
fprintf_attr ( add_fd , " cn " , " %s " , groupname ) ;
fprintf ( add_fd , " gidNumber: %d \n " , ldif_gid ) ;
fprintf ( add_fd , " sambaSID: %s \n " , groupmap - > sambaSID ) ;
fprintf ( add_fd , " sambaGroupType: %d \n " , grouptype ) ;
fprintf_attr ( add_fd , " displayName " , " %s " , groupname ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
SAFE_FREE ( group_attr ) ;
/* Return */
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS fetch_account_info_to_ldif ( TALLOC_CTX * mem_ctx ,
struct netr_DELTA_USER * r ,
GROUPMAP * groupmap ,
ACCOUNTMAP * accountmap ,
FILE * add_fd ,
const char * sid ,
const char * suffix ,
int alloced )
{
fstring username , logonscript , homedrive , homepath = " " , homedir = " " ;
fstring hex_nt_passwd , hex_lm_passwd ;
fstring description , profilepath , fullname , sambaSID ;
uchar lm_passwd [ 16 ] , nt_passwd [ 16 ] ;
char * flags , * user_rdn ;
const char * ou ;
const char * nopasswd = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX " ;
static uchar zero_buf [ 16 ] ;
uint32 rid = 0 , group_rid = 0 , gidNumber = 0 ;
time_t unix_time ;
int i ;
/* Get the username */
fstrcpy ( username , r - > account_name . string ) ;
/* Get the rid */
rid = r - > rid ;
/* Map the rid and username for group member info later */
accountmap - > rid = rid ;
accountmap - > cn = talloc_strdup ( mem_ctx , username ) ;
NT_STATUS_HAVE_NO_MEMORY ( accountmap - > cn ) ;
/* Get the home directory */
if ( r - > acct_flags & ACB_NORMAL ) {
fstrcpy ( homedir , r - > home_directory . string ) ;
if ( ! * homedir ) {
snprintf ( homedir , sizeof ( homedir ) , " /home/%s " , username ) ;
} else {
snprintf ( homedir , sizeof ( homedir ) , " /nobodyshomedir " ) ;
}
ou = lp_ldap_user_suffix ( ) ;
} else {
ou = lp_ldap_machine_suffix ( ) ;
snprintf ( homedir , sizeof ( homedir ) , " /machinehomedir " ) ;
}
/* Get the logon script */
fstrcpy ( logonscript , r - > logon_script . string ) ;
/* Get the home drive */
fstrcpy ( homedrive , r - > home_drive . string ) ;
/* Get the home path */
fstrcpy ( homepath , r - > home_directory . string ) ;
/* Get the description */
fstrcpy ( description , r - > description . string ) ;
/* Get the display name */
fstrcpy ( fullname , r - > full_name . string ) ;
/* Get the profile path */
fstrcpy ( profilepath , r - > profile_path . string ) ;
/* Get lm and nt password data */
if ( memcmp ( r - > lmpassword . hash , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( r - > rid , r - > lmpassword . hash , lm_passwd , 0 ) ;
pdb_sethexpwd ( hex_lm_passwd , lm_passwd , r - > acct_flags ) ;
} else {
pdb_sethexpwd ( hex_lm_passwd , NULL , 0 ) ;
}
if ( memcmp ( r - > ntpassword . hash , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( r - > rid , r - > ntpassword . hash , nt_passwd , 0 ) ;
pdb_sethexpwd ( hex_nt_passwd , nt_passwd , r - > acct_flags ) ;
} else {
pdb_sethexpwd ( hex_nt_passwd , NULL , 0 ) ;
}
unix_time = nt_time_to_unix ( r - > last_password_change ) ;
/* Increment the uid for the new user */
ldif_uid + + ;
/* Set up group id and sambaSID for the user */
group_rid = r - > primary_gid ;
for ( i = 0 ; i < alloced ; i + + ) {
if ( groupmap [ i ] . rid = = group_rid ) break ;
}
if ( i = = alloced ) {
DEBUG ( 1 , ( " Could not find rid %d in groupmap array \n " ,
group_rid ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
gidNumber = groupmap [ i ] . gidNumber ;
snprintf ( sambaSID , sizeof ( sambaSID ) , groupmap [ i ] . sambaSID ) ;
/* Set up sambaAcctFlags */
flags = pdb_encode_acct_ctrl ( r - > acct_flags ,
NEW_PW_FORMAT_SPACE_PADDED_LEN ) ;
/* Add the user to the temporary add ldif file */
/* this isn't quite right...we can't assume there's just OU=. jmcd */
user_rdn = sstring_sub ( ou , ' = ' , ' , ' ) ;
fprintf ( add_fd , " # %s, %s, %s \n " , username , user_rdn , suffix ) ;
fprintf_attr ( add_fd , " dn " , " uid=%s,ou=%s,%s " , username , user_rdn ,
suffix ) ;
SAFE_FREE ( user_rdn ) ;
fprintf ( add_fd , " ObjectClass: top \n " ) ;
fprintf ( add_fd , " objectClass: inetOrgPerson \n " ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXACCOUNT ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " objectClass: shadowAccount \n " ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_SAMBASAMACCOUNT ) ;
2008-06-16 14:37:57 +04:00
fprintf_attr ( add_fd , " cn " , " %s " , username ) ;
fprintf_attr ( add_fd , " sn " , " %s " , username ) ;
fprintf_attr ( add_fd , " uid " , " %s " , username ) ;
fprintf ( add_fd , " uidNumber: %d \n " , ldif_uid ) ;
fprintf ( add_fd , " gidNumber: %d \n " , gidNumber ) ;
fprintf_attr ( add_fd , " homeDirectory " , " %s " , homedir ) ;
if ( * homepath )
fprintf_attr ( add_fd , " sambaHomePath " , " %s " , homepath ) ;
if ( * homedrive )
fprintf_attr ( add_fd , " sambaHomeDrive " , " %s " , homedrive ) ;
if ( * logonscript )
fprintf_attr ( add_fd , " sambaLogonScript " , " %s " , logonscript ) ;
fprintf ( add_fd , " loginShell: %s \n " ,
( ( r - > acct_flags & ACB_NORMAL ) ?
" /bin/bash " : " /bin/false " ) ) ;
fprintf ( add_fd , " gecos: System User \n " ) ;
if ( * description )
fprintf_attr ( add_fd , " description " , " %s " , description ) ;
fprintf ( add_fd , " sambaSID: %s-%d \n " , sid , rid ) ;
fprintf ( add_fd , " sambaPrimaryGroupSID: %s \n " , sambaSID ) ;
if ( * fullname )
fprintf_attr ( add_fd , " displayName " , " %s " , fullname ) ;
if ( * profilepath )
fprintf_attr ( add_fd , " sambaProfilePath " , " %s " , profilepath ) ;
if ( strcmp ( nopasswd , hex_lm_passwd ) ! = 0 )
fprintf ( add_fd , " sambaLMPassword: %s \n " , hex_lm_passwd ) ;
if ( strcmp ( nopasswd , hex_nt_passwd ) ! = 0 )
fprintf ( add_fd , " sambaNTPassword: %s \n " , hex_nt_passwd ) ;
fprintf ( add_fd , " sambaPwdLastSet: %d \n " , ( int ) unix_time ) ;
fprintf ( add_fd , " sambaAcctFlags: %s \n " , flags ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Return */
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS fetch_alias_info_to_ldif ( TALLOC_CTX * mem_ctx ,
struct netr_DELTA_ALIAS * r ,
GROUPMAP * groupmap ,
FILE * add_fd ,
const char * sid ,
const char * suffix ,
enum netr_SamDatabaseID database_id )
{
fstring aliasname , description ;
uint32 grouptype = 0 , g_rid = 0 ;
char * group_attr = sstring_sub ( lp_ldap_group_suffix ( ) , ' = ' , ' , ' ) ;
/* Get the alias name */
fstrcpy ( aliasname , r - > alias_name . string ) ;
/* Get the alias description */
fstrcpy ( description , r - > description . string ) ;
/* Set up the group type */
switch ( database_id ) {
case SAM_DATABASE_DOMAIN :
grouptype = 4 ;
break ;
case SAM_DATABASE_BUILTIN :
grouptype = 5 ;
break ;
default :
grouptype = 4 ;
break ;
}
/*
These groups are entered by populate_ldap_for_ldif
Note that populate creates a group called Relicators ,
but NT returns a group called Replicator
*/
if ( strcmp ( aliasname , " Domain Admins " ) = = 0 | |
strcmp ( aliasname , " Domain Users " ) = = 0 | |
strcmp ( aliasname , " Domain Guests " ) = = 0 | |
strcmp ( aliasname , " Domain Computers " ) = = 0 | |
strcmp ( aliasname , " Administrators " ) = = 0 | |
strcmp ( aliasname , " Print Operators " ) = = 0 | |
strcmp ( aliasname , " Backup Operators " ) = = 0 | |
strcmp ( aliasname , " Replicator " ) = = 0 ) {
SAFE_FREE ( group_attr ) ;
return NT_STATUS_OK ;
} else {
/* Increment the gid for the new group */
ldif_gid + + ;
}
/* Map the group rid and gid */
g_rid = r - > rid ;
groupmap - > gidNumber = ldif_gid ;
groupmap - > sambaSID = talloc_asprintf ( mem_ctx , " %s-%d " , sid , g_rid ) ;
NT_STATUS_HAVE_NO_MEMORY ( groupmap - > sambaSID ) ;
/* Write the data to the temporary add ldif file */
fprintf ( add_fd , " # %s, %s, %s \n " , aliasname , group_attr ,
suffix ) ;
fprintf_attr ( add_fd , " dn " , " cn=%s,ou=%s,%s " , aliasname , group_attr ,
suffix ) ;
2008-07-18 15:15:05 +04:00
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_POSIXGROUP ) ;
fprintf ( add_fd , " objectClass: %s \n " , LDAP_OBJ_GROUPMAP ) ;
2008-06-16 14:37:57 +04:00
fprintf ( add_fd , " cn: %s \n " , aliasname ) ;
fprintf ( add_fd , " gidNumber: %d \n " , ldif_gid ) ;
fprintf ( add_fd , " sambaSID: %s \n " , groupmap - > sambaSID ) ;
fprintf ( add_fd , " sambaGroupType: %d \n " , grouptype ) ;
fprintf_attr ( add_fd , " displayName " , " %s " , aliasname ) ;
if ( description [ 0 ] )
fprintf_attr ( add_fd , " description " , " %s " , description ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
SAFE_FREE ( group_attr ) ;
/* Return */
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS fetch_groupmem_info_to_ldif ( struct netr_DELTA_GROUP_MEMBER * r ,
uint32_t id_rid ,
GROUPMAP * groupmap ,
ACCOUNTMAP * accountmap ,
FILE * mod_fd , int alloced )
{
fstring group_dn ;
uint32 group_rid = 0 , rid = 0 ;
int i , j , k ;
/* Get the dn for the group */
if ( r - > num_rids > 0 ) {
group_rid = id_rid ;
for ( j = 0 ; j < alloced ; j + + ) {
if ( groupmap [ j ] . rid = = group_rid ) break ;
}
if ( j = = alloced ) {
DEBUG ( 1 , ( " Could not find rid %d in groupmap array \n " ,
group_rid ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
snprintf ( group_dn , sizeof ( group_dn ) , " %s " , groupmap [ j ] . group_dn ) ;
fprintf ( mod_fd , " dn: %s \n " , group_dn ) ;
/* Get the cn for each member */
for ( i = 0 ; i < r - > num_rids ; i + + ) {
rid = r - > rids [ i ] ;
for ( k = 0 ; k < alloced ; k + + ) {
if ( accountmap [ k ] . rid = = rid ) break ;
}
if ( k = = alloced ) {
DEBUG ( 1 , ( " Could not find rid %d in "
" accountmap array \n " , rid ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
fprintf ( mod_fd , " memberUid: %s \n " , accountmap [ k ] . cn ) ;
}
fprintf ( mod_fd , " \n " ) ;
}
fflush ( mod_fd ) ;
/* Return */
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS ldif_init_context ( TALLOC_CTX * mem_ctx ,
enum netr_SamDatabaseID database_id ,
const char * ldif_filename ,
const char * domain_sid_str ,
struct samsync_ldif_context * * ctx )
{
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
struct samsync_ldif_context * r ;
const char * add_template = " /tmp/add.ldif.XXXXXX " ;
const char * mod_template = " /tmp/mod.ldif.XXXXXX " ;
const char * builtin_sid = " S-1-5-32 " ;
/* Get other smb.conf data */
if ( ! ( lp_workgroup ( ) ) | | ! * ( lp_workgroup ( ) ) ) {
DEBUG ( 0 , ( " workgroup missing from smb.conf--exiting \n " ) ) ;
exit ( 1 ) ;
}
/* Get the ldap suffix */
if ( ! ( lp_ldap_suffix ( ) ) | | ! * ( lp_ldap_suffix ( ) ) ) {
DEBUG ( 0 , ( " ldap suffix missing from smb.conf--exiting \n " ) ) ;
exit ( 1 ) ;
}
if ( * ctx & & ( * ctx ) - > initialized ) {
return NT_STATUS_OK ;
}
r = TALLOC_ZERO_P ( mem_ctx , struct samsync_ldif_context ) ;
NT_STATUS_HAVE_NO_MEMORY ( r ) ;
/* Get the ldap suffix */
r - > suffix = lp_ldap_suffix ( ) ;
/* Ensure we have an output file */
if ( ldif_filename ) {
r - > ldif_file = fopen ( ldif_filename , " a " ) ;
} else {
r - > ldif_file = stdout ;
}
if ( ! r - > ldif_file ) {
fprintf ( stderr , " Could not open %s \n " , ldif_filename ) ;
DEBUG ( 1 , ( " Could not open %s \n " , ldif_filename ) ) ;
status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
r - > add_template = talloc_strdup ( mem_ctx , add_template ) ;
r - > mod_template = talloc_strdup ( mem_ctx , mod_template ) ;
if ( ! r - > add_template | | ! r - > mod_template ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
r - > add_name = talloc_strdup ( mem_ctx , add_template ) ;
r - > mod_name = talloc_strdup ( mem_ctx , mod_template ) ;
if ( ! r - > add_name | | ! r - > mod_name ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
/* Open the add and mod ldif files */
if ( ! ( r - > add_file = fdopen ( smb_mkstemp ( r - > add_name ) , " w " ) ) ) {
DEBUG ( 1 , ( " Could not open %s \n " , r - > add_name ) ) ;
status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! ( r - > mod_file = fdopen ( smb_mkstemp ( r - > mod_name ) , " w " ) ) ) {
DEBUG ( 1 , ( " Could not open %s \n " , r - > mod_name ) ) ;
status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Allocate initial memory for groupmap and accountmap arrays */
r - > groupmap = TALLOC_ZERO_ARRAY ( mem_ctx , GROUPMAP , 8 ) ;
r - > accountmap = TALLOC_ZERO_ARRAY ( mem_ctx , ACCOUNTMAP , 8 ) ;
if ( r - > groupmap = = NULL | | r - > accountmap = = NULL ) {
DEBUG ( 1 , ( " GROUPMAP talloc failed \n " ) ) ;
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
/* Remember how many we malloced */
r - > num_alloced = 8 ;
/* Initial database population */
if ( database_id = = SAM_DATABASE_DOMAIN ) {
status = populate_ldap_for_ldif ( domain_sid_str ,
r - > suffix ,
builtin_sid ,
r - > add_file ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
status = map_populate_groups ( mem_ctx ,
r - > groupmap ,
r - > accountmap ,
domain_sid_str ,
r - > suffix ,
builtin_sid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
}
r - > initialized = true ;
* ctx = r ;
return NT_STATUS_OK ;
done :
TALLOC_FREE ( r ) ;
return status ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void ldif_free_context ( struct samsync_ldif_context * r )
{
if ( ! r ) {
return ;
}
/* Close and delete the ldif files */
if ( r - > add_file ) {
fclose ( r - > add_file ) ;
}
if ( ( r - > add_name ! = NULL ) & &
strcmp ( r - > add_name , r - > add_template ) & & ( unlink ( r - > add_name ) ) ) {
DEBUG ( 1 , ( " unlink(%s) failed, error was (%s) \n " ,
r - > add_name , strerror ( errno ) ) ) ;
}
if ( r - > mod_file ) {
fclose ( r - > mod_file ) ;
}
if ( ( r - > mod_name ! = NULL ) & &
strcmp ( r - > mod_name , r - > mod_template ) & & ( unlink ( r - > mod_name ) ) ) {
DEBUG ( 1 , ( " unlink(%s) failed, error was (%s) \n " ,
r - > mod_name , strerror ( errno ) ) ) ;
}
if ( r - > ldif_file & & ( r - > ldif_file ! = stdout ) ) {
fclose ( r - > ldif_file ) ;
}
TALLOC_FREE ( r ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void ldif_write_output ( enum netr_SamDatabaseID database_id ,
struct samsync_ldif_context * l )
{
/* Write ldif data to the user's file */
if ( database_id = = SAM_DATABASE_DOMAIN ) {
fprintf ( l - > ldif_file ,
" # SAM_DATABASE_DOMAIN: ADD ENTITIES \n " ) ;
fprintf ( l - > ldif_file ,
" # ================================= \n \n " ) ;
fflush ( l - > ldif_file ) ;
} else if ( database_id = = SAM_DATABASE_BUILTIN ) {
fprintf ( l - > ldif_file ,
" # SAM_DATABASE_BUILTIN: ADD ENTITIES \n " ) ;
fprintf ( l - > ldif_file ,
" # ================================== \n \n " ) ;
fflush ( l - > ldif_file ) ;
}
fseek ( l - > add_file , 0 , SEEK_SET ) ;
transfer_file ( fileno ( l - > add_file ) , fileno ( l - > ldif_file ) , ( size_t ) - 1 ) ;
if ( database_id = = SAM_DATABASE_DOMAIN ) {
fprintf ( l - > ldif_file ,
" # SAM_DATABASE_DOMAIN: MODIFY ENTITIES \n " ) ;
fprintf ( l - > ldif_file ,
" # ==================================== \n \n " ) ;
fflush ( l - > ldif_file ) ;
} else if ( database_id = = SAM_DATABASE_BUILTIN ) {
fprintf ( l - > ldif_file ,
" # SAM_DATABASE_BUILTIN: MODIFY ENTITIES \n " ) ;
fprintf ( l - > ldif_file ,
" # ===================================== \n \n " ) ;
fflush ( l - > ldif_file ) ;
}
fseek ( l - > mod_file , 0 , SEEK_SET ) ;
transfer_file ( fileno ( l - > mod_file ) , fileno ( l - > ldif_file ) , ( size_t ) - 1 ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS fetch_sam_entry_ldif ( TALLOC_CTX * mem_ctx ,
enum netr_SamDatabaseID database_id ,
struct netr_DELTA_ENUM * r ,
struct samsync_context * ctx ,
uint32_t * a_index ,
uint32_t * g_index )
{
union netr_DELTA_UNION u = r - > delta_union ;
union netr_DELTA_ID_UNION id = r - > delta_id_union ;
struct samsync_ldif_context * l =
talloc_get_type_abort ( ctx - > private_data , struct samsync_ldif_context ) ;
switch ( r - > delta_type ) {
case NETR_DELTA_DOMAIN :
break ;
case NETR_DELTA_GROUP :
fetch_group_info_to_ldif ( mem_ctx ,
u . group ,
& l - > groupmap [ * g_index ] ,
l - > add_file ,
ctx - > domain_sid_str ,
l - > suffix ) ;
( * g_index ) + + ;
break ;
case NETR_DELTA_USER :
fetch_account_info_to_ldif ( mem_ctx ,
u . user ,
l - > groupmap ,
& l - > accountmap [ * a_index ] ,
l - > add_file ,
ctx - > domain_sid_str ,
l - > suffix ,
l - > num_alloced ) ;
( * a_index ) + + ;
break ;
case NETR_DELTA_ALIAS :
fetch_alias_info_to_ldif ( mem_ctx ,
u . alias ,
& l - > groupmap [ * g_index ] ,
l - > add_file ,
ctx - > domain_sid_str ,
l - > suffix ,
database_id ) ;
( * g_index ) + + ;
break ;
case NETR_DELTA_GROUP_MEMBER :
fetch_groupmem_info_to_ldif ( u . group_member ,
id . rid ,
l - > groupmap ,
l - > accountmap ,
l - > mod_file ,
l - > num_alloced ) ;
break ;
case NETR_DELTA_ALIAS_MEMBER :
case NETR_DELTA_POLICY :
case NETR_DELTA_ACCOUNT :
case NETR_DELTA_TRUSTED_DOMAIN :
case NETR_DELTA_SECRET :
case NETR_DELTA_RENAME_GROUP :
case NETR_DELTA_RENAME_USER :
case NETR_DELTA_RENAME_ALIAS :
case NETR_DELTA_DELETE_GROUP :
case NETR_DELTA_DELETE_USER :
case NETR_DELTA_MODIFY_COUNT :
default :
break ;
} /* end of switch */
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS ldif_realloc_maps ( TALLOC_CTX * mem_ctx ,
struct samsync_ldif_context * l ,
uint32_t num_entries )
{
/* Re-allocate memory for groupmap and accountmap arrays */
l - > groupmap = TALLOC_REALLOC_ARRAY ( mem_ctx ,
l - > groupmap ,
GROUPMAP ,
num_entries + l - > num_alloced ) ;
l - > accountmap = TALLOC_REALLOC_ARRAY ( mem_ctx ,
l - > accountmap ,
ACCOUNTMAP ,
num_entries + l - > num_alloced ) ;
if ( l - > groupmap = = NULL | | l - > accountmap = = NULL ) {
DEBUG ( 1 , ( " GROUPMAP talloc failed \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
/* Initialize the new records */
memset ( & ( l - > groupmap [ l - > num_alloced ] ) , 0 ,
sizeof ( GROUPMAP ) * num_entries ) ;
memset ( & ( l - > accountmap [ l - > num_alloced ] ) , 0 ,
sizeof ( ACCOUNTMAP ) * num_entries ) ;
/* Remember how many we alloced this time */
l - > num_alloced + = num_entries ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS fetch_sam_entries_ldif ( TALLOC_CTX * mem_ctx ,
enum netr_SamDatabaseID database_id ,
struct netr_DELTA_ENUM_ARRAY * r ,
2008-06-27 02:46:38 +04:00
bool last_query ,
2008-06-16 14:37:57 +04:00
struct samsync_context * ctx )
{
NTSTATUS status ;
int i ;
uint32_t g_index = 0 , a_index = 0 ;
struct samsync_ldif_context * ldif_ctx =
( struct samsync_ldif_context * ) ctx - > private_data ;
status = ldif_init_context ( mem_ctx ,
database_id ,
2008-06-16 15:49:05 +04:00
ctx - > output_filename ,
2008-06-16 14:37:57 +04:00
ctx - > domain_sid_str ,
& ldif_ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto failed ;
}
ctx - > private_data = ldif_ctx ;
status = ldif_realloc_maps ( mem_ctx , ldif_ctx , r - > num_deltas ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto failed ;
}
for ( i = 0 ; i < r - > num_deltas ; i + + ) {
status = fetch_sam_entry_ldif ( mem_ctx , database_id ,
& r - > delta_enum [ i ] , ctx ,
2008-06-17 21:49:58 +04:00
& a_index , & g_index ) ;
2008-06-16 14:37:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto failed ;
}
}
/* This was the last query */
2008-06-27 02:46:38 +04:00
if ( last_query ) {
2008-06-16 14:37:57 +04:00
ldif_write_output ( database_id , ldif_ctx ) ;
2008-06-17 21:49:58 +04:00
if ( ldif_ctx - > ldif_file ! = stdout ) {
ctx - > result_message = talloc_asprintf ( mem_ctx ,
" Vampired %d accounts and %d groups to %s " ,
a_index , g_index , ctx - > output_filename ) ;
}
2008-06-16 14:37:57 +04:00
ldif_free_context ( ldif_ctx ) ;
ctx - > private_data = NULL ;
}
return NT_STATUS_OK ;
failed :
ldif_free_context ( ldif_ctx ) ;
ctx - > private_data = NULL ;
return status ;
}