moving more code around.
authorGerald Carter <jerry@samba.org>
Fri, 11 Jul 2003 05:33:40 +0000 (05:33 +0000)
committerGerald Carter <jerry@samba.org>
Fri, 11 Jul 2003 05:33:40 +0000 (05:33 +0000)
  * move rid allocation into IDMAP.  See comments in _api_samr_create_user()
  * add winbind delete user/group functions

I'm checking this in to sync up with everyone.  But I'm going to split
the add a separate winbindd_allocate_rid() function for systems
that have an 'add user script' but need idmap to give them a RID.
Life would be so much simplier without 'enable rid algorithm'.
The current RID allocation is horrible due to this one fact.
Tested idmap_tdb but not idmap_ldap yet.  Will do that tomorrow.

Nothing has changed in the way a samba domain is represented, stored,
or search in the directory so things should be ok with previous installations.

going to bed now.
(This used to be commit 0463045cc7ff177fab44b25faffad5bf7140244d)

20 files changed:
source3/auth/auth_util.c
source3/groupdb/mapping.c
source3/include/idmap.h
source3/lib/smbldap.c
source3/nsswitch/wb_client.c
source3/nsswitch/wbinfo.c
source3/nsswitch/winbindd_acct.c
source3/nsswitch/winbindd_nss.h
source3/nsswitch/winbindd_user.c
source3/passdb/passdb.c
source3/passdb/pdb_ldap.c
source3/passdb/pdb_smbpasswd.c
source3/passdb/pdb_tdb.c
source3/rpc_server/srv_samr_nt.c
source3/sam/idmap.c
source3/sam/idmap_ldap.c
source3/sam/idmap_tdb.c
source3/sam/idmap_util.c
source3/utils/net_rpc_samsync.c
source3/utils/pdbedit.c

index 51cd1994f91c6e72b05ec9bcd358dd3166395155..3f9c120cfb1c11fbe87340b160cca1ebba8a5f21 100644 (file)
@@ -56,10 +56,12 @@ static int smb_create_user(const char *domain, const char *unix_username, const
 
 /****************************************************************************
  Add and Delete UNIX users on demand, based on NTSTATUS codes.
+ We don't care about RID's here so ignore.
 ****************************************************************************/
 
 void auth_add_user_script(const char *domain, const char *username)
 {
+       uint32 rid;
        /*
         * User validated ok against Domain controller.
         * If the admin wants us to try and create a UNIX
@@ -75,8 +77,10 @@ void auth_add_user_script(const char *domain, const char *username)
                   However, a host set for 'security = server' might run winbindd for 
                   account allocation */
                   
-               if ( !winbind_create_user(username) )
+               if ( !winbind_create_user(username, NULL) ) {
                        DEBUG(5,("auth_add_user_script: winbindd_create_user() failed\n"));
+                       rid = 0;
+               }
        }
 }
 
index e769b4dd9daf64ced3aed13c09e817342361fe2b..8a6f5148605998b9474cf124b258b99e1893ffbf 100644 (file)
@@ -756,7 +756,7 @@ int smb_create_group(char *unix_group, gid_t *new_gid)
 
        /* Try winbindd */
 
-       if ( winbind_create_group( unix_group ) ) {
+       if ( winbind_create_group( unix_group, NULL ) ) {
                DEBUG(3,("smb_create_group: winbindd created the group (%s)\n",
                        unix_group));
                return 0;
@@ -783,15 +783,13 @@ int smb_delete_group(char *unix_group)
                DEBUG(3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
                return ret;
        }
-#if 0  
+
        if ( winbind_delete_group( unix_group ) ) {
                DEBUG(3,("smb_delete_group: winbindd deleted the group (%s)\n",
                        unix_group));
                return 0;
        }
                
-#endif
-               
        return -1;
 }
 
index 7da3718d19721b4d7ff7bda5c2f7377e17c6422d..ae7e4e5101b044624bb12853e2781e79eb9dce3e 100644 (file)
@@ -42,6 +42,7 @@ struct idmap_methods {
        /* Called when backend is first loaded */
        NTSTATUS (*init)( char *params );
 
+       NTSTATUS (*allocate_rid)(uint32 *rid, int rid_type);
        NTSTATUS (*allocate_id)(unid_t *id, int id_type);
        NTSTATUS (*get_sid_from_id)(DOM_SID *sid, unid_t id, int id_type);
        NTSTATUS (*get_id_from_sid)(unid_t *id, int *id_type, const DOM_SID *sid);
index cba73d386c4356ee4bee6aad7150e108149ced52..21e3383acdccdedd95e9e44da087861962654dba 100644 (file)
@@ -1110,3 +1110,151 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_
        return NT_STATUS_OK;
 }
 
+/**********************************************************************
+ Add the sambaDomain to LDAP, so we don't have to search for this stuff
+ again.  This is a once-add operation for now.
+
+ TODO:  Add other attributes, and allow modification.
+*********************************************************************/
+static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, 
+                                    const char *domain_name) 
+{
+       fstring sid_string;
+       fstring algorithmic_rid_base_string;
+       pstring filter, dn;
+       LDAPMod **mods = NULL;
+       int rc;
+       int ldap_op;
+       LDAPMessage *result = NULL;
+       int num_result;
+       char **attr_list;
+
+       slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))", 
+                 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), 
+                 domain_name, LDAP_OBJ_DOMINFO);
+
+       attr_list = get_attr_list( dominfo_attr_list );
+       rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result);
+       free_attr_list( attr_list );
+
+       if (rc != LDAP_SUCCESS) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       num_result = ldap_count_entries(ldap_state->ldap_struct, result);
+       
+       if (num_result > 1) {
+               DEBUG (0, ("More than domain with that name exists: bailing out!\n"));
+               ldap_msgfree(result);
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+       
+       /* Check if we need to add an entry */
+       DEBUG(3,("Adding new domain\n"));
+       ldap_op = LDAP_MOD_ADD;
+
+       snprintf(dn, sizeof(dn), "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
+               domain_name, lp_ldap_suffix());
+
+       /* Free original search */
+       ldap_msgfree(result);
+
+       /* make the changes - the entry *must* not already have samba attributes */
+       smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), 
+               domain_name);
+
+       /* If we don't have an entry, then ask secrets.tdb for what it thinks.  
+          It may choose to make it up */
+
+       sid_to_string(sid_string, get_global_sam_sid());
+       smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), sid_string);
+
+       slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string) - 1, "%i", algorithmic_rid_base());
+       smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE), 
+                       algorithmic_rid_base_string);
+       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
+
+       switch(ldap_op)
+       {
+       case LDAP_MOD_ADD: 
+               rc = smbldap_add(ldap_state, dn, mods);
+               break;
+       case LDAP_MOD_REPLACE: 
+               rc = smbldap_modify(ldap_state, dn, mods);
+               break;
+       default:        
+               DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+       
+       if (rc!=LDAP_SUCCESS) {
+               char *ld_error = NULL;
+               ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+               DEBUG(1,("failed to %s domain dn= %s with: %s\n\t%s\n",
+                      ldap_op == LDAP_MOD_ADD ? "add" : "modify",
+                      dn, ldap_err2string(rc),
+                      ld_error?ld_error:"unknown"));
+               SAFE_FREE(ld_error);
+
+               ldap_mods_free(mods, True);
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       DEBUG(2,("added: domain = %s in the LDAP database\n", domain_name));
+       ldap_mods_free(mods, True);
+       return NT_STATUS_OK;
+}
+
+/**********************************************************************
+Search for the domain info entry
+*********************************************************************/
+NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
+                                    LDAPMessage ** result, const char *domain_name,
+                                    BOOL try_add)
+{
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+       pstring filter;
+       int rc;
+       char **attr_list;
+       int count;
+
+       snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
+               LDAP_OBJ_DOMINFO,
+               get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), 
+               domain_name);
+
+       DEBUG(2, ("Searching for:[%s]\n", filter));
+
+
+       attr_list = get_attr_list( dominfo_attr_list );
+       rc = smbldap_search_suffix(ldap_state, filter, attr_list , result);
+       free_attr_list( attr_list );
+
+       if (rc != LDAP_SUCCESS) {
+               DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc)));
+               DEBUG(2,("Query was: %s, %s\n", lp_ldap_suffix(), filter));
+       } else if (ldap_count_entries(ldap_state->ldap_struct, *result) < 1) {
+               DEBUG(3, ("Got no domain info entries for domain\n"));
+               ldap_msgfree(*result);
+               *result = NULL;
+               if (try_add && NT_STATUS_IS_OK(ret = add_new_domain_info(ldap_state, domain_name))) {
+                       return smbldap_search_domain_info(ldap_state, result, domain_name, False);
+               } 
+               else {
+                       DEBUG(0, ("Adding domain info for %s failed with %s\n", 
+                               domain_name, nt_errstr(ret)));
+                       return ret;
+               }
+       } else if ((count = ldap_count_entries(ldap_state->ldap_struct, *result)) > 1) {
+               DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n",
+                         count, domain_name));
+               ldap_msgfree(*result);
+               *result = NULL;
+               return ret;
+       } else {
+               return NT_STATUS_OK;
+       }
+       
+       return ret;
+}
+
index 26a0e58191f4357cd3745686da25c8e0de162a21..eb9a7e99958d96643f6c6f487ca6ea0222a4ec54 100644 (file)
@@ -371,7 +371,7 @@ BOOL winbind_ping( void )
  Ask winbindd to create a local user
 **********************************************************************/
 
-BOOL winbind_create_user( const char *name )
+BOOL winbind_create_user( const char *name, uint32 *rid )
 {
        struct winbindd_request request;
        struct winbindd_response response;
@@ -384,6 +384,11 @@ BOOL winbind_create_user( const char *name )
                return False;
                
        DEBUG(10,("winbind_create_user: %s\n", name));
+       
+       /* see if the caller wants a new RID returned */
+       
+       if ( rid ) 
+               request.flags = WBFLAG_ALLOCATE_RID;
 
        fstrcpy( request.data.acct_mgt.username, name );
        fstrcpy( request.data.acct_mgt.groupname, "" );
@@ -392,6 +397,9 @@ BOOL winbind_create_user( const char *name )
        
        result = winbindd_request( WINBINDD_CREATE_USER, &request, &response);
        
+       if ( rid )
+               *rid = response.data.rid;
+       
        return result == NSS_STATUS_SUCCESS;
 }
 
@@ -399,7 +407,7 @@ BOOL winbind_create_user( const char *name )
  Ask winbindd to create a local group
 **********************************************************************/
 
-BOOL winbind_create_group( const char *name )
+BOOL winbind_create_group( const char *name, uint32 *rid )
 {
        struct winbindd_request request;
        struct winbindd_response response;
@@ -413,12 +421,20 @@ BOOL winbind_create_group( const char *name )
                
        DEBUG(10,("winbind_create_group: %s\n", name));
 
+       /* see if the caller wants a new RID returned */
+       
+       if ( rid ) 
+               request.flags = WBFLAG_ALLOCATE_RID;
+               
        fstrcpy( request.data.acct_mgt.groupname, name );
        
        ZERO_STRUCT(response);
        
        result = winbindd_request( WINBINDD_CREATE_GROUP, &request, &response);
        
+       if ( rid )
+               *rid = response.data.rid;
+       
        return result == NSS_STATUS_SUCCESS;
 }
 
@@ -510,4 +526,58 @@ BOOL winbind_set_user_primary_group( const char *user, const char *group )
 }
 
 
+/**********************************************************************
+ Ask winbindd to remove a user from its lists of accounts
+**********************************************************************/
+
+BOOL winbind_delete_user( const char *user )
+{
+       struct winbindd_request request;
+       struct winbindd_response response;
+       NSS_STATUS result;
+       
+       if ( !lp_winbind_enable_local_accounts() )
+               return False;
+               
+       if ( !user )
+               return False;
+               
+       DEBUG(10,("winbind_delete_user: user (%s)\n", user));
+
+       fstrcpy( request.data.acct_mgt.username, user );
+       
+       ZERO_STRUCT(response);
+       
+       result = winbindd_request( WINBINDD_DELETE_USER, &request, &response);
+       
+       return result == NSS_STATUS_SUCCESS;
+}
+
+/**********************************************************************
+ Ask winbindd to remove a group from its lists of accounts
+**********************************************************************/
+
+BOOL winbind_delete_group( const char *group )
+{
+       struct winbindd_request request;
+       struct winbindd_response response;
+       NSS_STATUS result;
+       
+       if ( !lp_winbind_enable_local_accounts() )
+               return False;
+               
+       if ( !group )
+               return False;
+               
+       DEBUG(10,("winbind_delete_group: group (%s)\n", group));
+
+       fstrcpy( request.data.acct_mgt.groupname, group );
+       
+       ZERO_STRUCT(response);
+       
+       result = winbindd_request( WINBINDD_DELETE_GROUP, &request, &response);
+       
+       return result == NSS_STATUS_SUCCESS;
+}
+
 
index 6ebf6effa76c1cc69a7255c7542547c24ce3585a..f53379937043fb1a80e3a91579196faf809f5b8e 100644 (file)
@@ -526,16 +526,36 @@ static BOOL wbinfo_create_user(char *username)
        ZERO_STRUCT(request);
        ZERO_STRUCT(response);
 
+       request.flags = WBFLAG_ALLOCATE_RID;
        fstrcpy(request.data.acct_mgt.username, username);
 
        result = winbindd_request(WINBINDD_CREATE_USER, &request, &response);
        
-       if (response.data.auth.nt_status)
-               d_printf("error code was %s (0x%x)\nerror messsage was: %s\n", 
-                        response.data.auth.nt_status_string, 
-                        response.data.auth.nt_status,
-                        response.data.auth.error_string);
+       if ( result == NSS_STATUS_SUCCESS )
+               d_printf("New RID is %d\n", response.data.rid);
+       
+        return result == NSS_STATUS_SUCCESS;
+}
 
+/******************************************************************
+ remove a winbindd user
+******************************************************************/
+
+static BOOL wbinfo_delete_user(char *username)
+{
+       struct winbindd_request request;
+       struct winbindd_response response;
+        NSS_STATUS result;
+
+       /* Send off request */
+
+       ZERO_STRUCT(request);
+       ZERO_STRUCT(response);
+
+       fstrcpy(request.data.acct_mgt.username, username);
+
+       result = winbindd_request(WINBINDD_DELETE_USER, &request, &response);
+       
         return result == NSS_STATUS_SUCCESS;
 }
 
@@ -558,12 +578,28 @@ static BOOL wbinfo_create_group(char *groupname)
 
        result = winbindd_request(WINBINDD_CREATE_GROUP, &request, &response);
        
-       if (response.data.auth.nt_status)
-               d_printf("error code was %s (0x%x)\nerror messsage was: %s\n", 
-                        response.data.auth.nt_status_string, 
-                        response.data.auth.nt_status,
-                        response.data.auth.error_string);
+        return result == NSS_STATUS_SUCCESS;
+}
 
+/******************************************************************
+ remove a winbindd group
+******************************************************************/
+
+static BOOL wbinfo_delete_group(char *groupname)
+{
+       struct winbindd_request request;
+       struct winbindd_response response;
+        NSS_STATUS result;
+
+       /* Send off request */
+
+       ZERO_STRUCT(request);
+       ZERO_STRUCT(response);
+
+       fstrcpy(request.data.acct_mgt.groupname, groupname);
+
+       result = winbindd_request(WINBINDD_DELETE_GROUP, &request, &response);
+       
         return result == NSS_STATUS_SUCCESS;
 }
 
@@ -614,12 +650,6 @@ static BOOL wbinfo_add_user_to_group(char *string)
 
        result = winbindd_request(WINBINDD_ADD_USER_TO_GROUP, &request, &response);
        
-       if (response.data.auth.nt_status)
-               d_printf("error code was %s (0x%x)\nerror messsage was: %s\n", 
-                        response.data.auth.nt_status_string, 
-                        response.data.auth.nt_status,
-                        response.data.auth.error_string);
-
         return result == NSS_STATUS_SUCCESS;
 }
 
@@ -647,12 +677,6 @@ static BOOL wbinfo_remove_user_from_group(char *string)
 
        result = winbindd_request(WINBINDD_REMOVE_USER_FROM_GROUP, &request, &response);
        
-       if (response.data.auth.nt_status)
-               d_printf("error code was %s (0x%x)\nerror messsage was: %s\n", 
-                        response.data.auth.nt_status_string, 
-                        response.data.auth.nt_status,
-                        response.data.auth.error_string);
-
         return result == NSS_STATUS_SUCCESS;
 }
 
@@ -851,7 +875,9 @@ int main(int argc, char **argv)
                { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" },
                { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid", "SID" },
                { "create-user", 'c', POPT_ARG_STRING, &string_arg, 'c', "Create a local user account", "name" },
+               { "delete-user", 'x', POPT_ARG_STRING, &string_arg, 'x', "Delete a local user account", "name" },
                { "create-group", 'C', POPT_ARG_STRING, &string_arg, 'C', "Create a local group", "name" },
+               { "delete-group", 'X', POPT_ARG_STRING, &string_arg, 'X', "Delete a local group", "name" },
                { "add-to-group", 'o', POPT_ARG_STRING, &string_arg, 'o', "Add user to group", "user:group" },
                { "del-from-group", 'O', POPT_ARG_STRING, &string_arg, 'O', "Remove user from group", "user:group" },
                { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
@@ -1036,6 +1062,18 @@ int main(int argc, char **argv)
                                goto done;
                        }
                        break;
+               case 'x':
+                       if ( !wbinfo_delete_user(string_arg) ) {
+                               d_printf("Could not delete user account\n");
+                               goto done;
+                       }
+                       break;
+               case 'X':
+                       if ( !wbinfo_delete_group(string_arg) ) {
+                               d_printf("Could not delete group\n");
+                               goto done;
+                       }
+                       break;
                case 'P':
                        if (!wbinfo_ping()) {
                                d_printf("could not ping winbindd!\n");
index 2a3a6eb2bb072a7d69ceb16978bd1b69b7f13238..a1cd1d5f19a0dfbc7afe327fedd11f520ac7f162 100644 (file)
@@ -37,6 +37,29 @@ static TDB_CONTEXT *account_tdb;
 
 extern userdom_struct current_user_info;
 
+struct _check_primary_grp {
+       gid_t   gid;
+       BOOL    found;
+};
+
+/**********************************************************************
+**********************************************************************/
+
+static void free_winbindd_gr( WINBINDD_GR *grp )
+{
+       int i;
+
+       if ( !grp )
+               return;
+               
+       for ( i=0; i<grp->num_gr_mem; i++ )
+               SAFE_FREE( grp->gr_mem[i] );
+
+       SAFE_FREE( grp->gr_mem );
+       
+       return;
+}
+
 /*****************************************************************************
  Initialise auto-account database. 
 *****************************************************************************/
@@ -649,8 +672,17 @@ static BOOL wb_delgrpmember( WINBINDD_GR *grp, const char *user )
        if ( !found ) 
                return False;
 
-       memmove( grp->gr_mem[i], grp->gr_mem[i+1], sizeof(char*)*(grp->num_gr_mem-(i+1)) );
-       grp->num_gr_mem--;
+       /* still some remaining members */
+
+       if ( grp->num_gr_mem > 1 ) {
+               memmove( grp->gr_mem[i], grp->gr_mem[i+1], sizeof(char*)*(grp->num_gr_mem-(i+1)) );
+               grp->num_gr_mem--;
+       }
+       else {  /* last one */
+               free_winbindd_gr( grp );
+               grp->gr_mem = NULL;
+               grp->num_gr_mem = 0;
+       }
                                
        return True;
 }
@@ -658,34 +690,59 @@ static BOOL wb_delgrpmember( WINBINDD_GR *grp, const char *user )
 /**********************************************************************
 **********************************************************************/
 
-static void free_winbindd_gr( WINBINDD_GR *grp )
+static int cleangroups_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, 
+                      void *state)
 {
-       int i;
-
-       if ( !grp )
-               return;
+       int len;
+       fstring key;
+       char *name = (char*)state;
+       
+       snprintf( key, sizeof(key), "%s/NAME", WBKEY_GROUP );
+       len = strlen(key);
+       
+       /* if this is a group entry then, check the members */
+       
+       if ( (strncmp(kbuf.dptr, key, len) == 0) && dbuf.dptr ) {
+               WINBINDD_GR *grp;
                
-       for ( i=0; i<grp->num_gr_mem; i++ )
-               SAFE_FREE( grp->gr_mem[i] );
+               if ( !(grp = string2group( dbuf.dptr )) ) {
+                       DEBUG(0,("cleangroups_traverse_fn: Failure to parse [%s]\n",
+                               dbuf.dptr));
+                       return 0;
+               }
+               
+               /* just try to delete the user and rely on wb_delgrpmember()
+                  to tell you whether or not the group changed.  This is more 
+                  effecient than testing group membership first since the 
+                  checks for deleting a user from a group is essentially the 
+                  same as checking if he/she is a member */
+                  
+               if ( wb_delgrpmember( grp, name ) ) {
+                       DEBUG(10,("cleanupgroups_traverse_fn: Removed user (%s) from group (%s)\n",
+                               name, grp->gr_name));
+                       wb_storegrnam( grp );
+               }
+               
+               free_winbindd_gr( grp );
+       }
 
-       SAFE_FREE( grp->gr_mem );
-       
-       return;
+       return 0;
 }
 
 /**********************************************************************
 **********************************************************************/
 
-static BOOL wb_delete_user( const char *name)
+static BOOL wb_delete_user( WINBINDD_PW *pw)
 {
        char *namekey;
+       char *uidkey;
        
        if ( !account_tdb && !winbindd_accountdb_init() ) {
-               DEBUG(0,("wb_storepwnam: Failed to open winbindd account db\n"));
+               DEBUG(0,("wb_delete_user: Failed to open winbindd account db\n"));
                return False;
        }
 
-       namekey = acct_userkey_byname( name );
+       namekey = acct_userkey_byname( pw->pw_name );
        
        /* lock the main entry first */
        
@@ -694,20 +751,101 @@ static BOOL wb_delete_user( const char *name)
                return False;
        }
        
+       /* remove user from all groups */
+       
+       tdb_traverse(account_tdb, cleangroups_traverse_fn, (void *)pw->pw_name);
+       
+       /* remove the user */
+       uidkey = acct_userkey_byuid( pw->pw_uid );
        
        tdb_delete_bystring( account_tdb, namekey );
+       tdb_delete_bystring( account_tdb, uidkey );
+       
        tdb_unlock_bystring( account_tdb, namekey );
        
        return True;
 }
 
+/**********************************************************************
+**********************************************************************/
+
+static int isprimarygroup_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, 
+                                      TDB_DATA dbuf, void *params)
+{
+       int len;
+       fstring key;
+       struct _check_primary_grp *check = (struct _check_primary_grp*)params;
+       
+       snprintf( key, sizeof(key), "%s/NAME", WBKEY_PASSWD );
+       len = strlen(key);
+       
+       /* if this is a group entry then, check the members */
+       
+       if ( (strncmp(kbuf.dptr, key, len) == 0) && dbuf.dptr ) {
+               WINBINDD_PW *pw;;
+               
+               if ( !(pw = string2passwd( dbuf.dptr )) ) {
+                       DEBUG(0,("isprimarygroup_traverse_fn: Failure to parse [%s]\n",
+                               dbuf.dptr));
+                       return 0;
+               }
+               
+               if ( check->gid == pw->pw_gid ) {
+                       check->found = True;
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 
 /**********************************************************************
 **********************************************************************/
 
-static BOOL wb_delete_group( const char *name)
+static BOOL wb_delete_group( WINBINDD_GR *grp )
 {
-       return False;
+       struct _check_primary_grp check;
+       char *namekey;
+       char *gidkey;
+       
+       if ( !account_tdb && !winbindd_accountdb_init() ) {
+               DEBUG(0,("wb_delete_group: Failed to open winbindd account db\n"));
+               return False;
+       }
+       
+       /* lock the main entry first */
+       
+       namekey = acct_groupkey_byname( grp->gr_name ); 
+       if ( tdb_lock_bystring(account_tdb, namekey, 0) == -1 ) {
+               DEBUG(0,("wb_delete_group: Failed to lock %s\n", namekey));
+               return False;
+       }
+       
+       /* is this group the primary group for any user?  If 
+          so deny delete */
+          
+       check.found = False;    
+       tdb_traverse(account_tdb, isprimarygroup_traverse_fn, (void *)&check);
+       
+       if ( check.found ) {
+               DEBUG(4,("wb_delete_group: Cannot delete group (%s) since it "
+                       "is the primary group for some users\n", grp->gr_name));
+               return False;
+       }
+       
+       /* We're clear.  Delete the group */
+       
+       DEBUG(5,("wb_delete_group: Removing group (%s)\n", grp->gr_name));
+       
+       gidkey = acct_groupkey_bygid( grp->gr_gid );
+       
+       tdb_delete_bystring( account_tdb, namekey );
+       tdb_delete_bystring( account_tdb, gidkey );
+       
+       tdb_unlock_bystring( account_tdb, namekey );
+       
+       return True;
 }
 
 /**********************************************************************
@@ -722,6 +860,8 @@ enum winbindd_result winbindd_create_user(struct winbindd_cli_state *state)
        WINBINDD_GR *wb_grp;
        struct group *unix_grp;
        gid_t primary_gid;
+       uint32 flags = state->request.flags;
+       uint32 rid;
        
        if ( !state->privileged ) {
                DEBUG(2, ("winbindd_create_user: non-privileged access denied!\n"));
@@ -781,8 +921,27 @@ enum winbindd_result winbindd_create_user(struct winbindd_cli_state *state)
        
        pw.pw_uid = id.uid;
        pw.pw_gid = primary_gid;
+       
+       /* store the new entry */
+       
+       if ( !wb_storepwnam(&pw) )
+               return WINBINDD_ERROR;
+               
+       /* do we need a new RID? */
+       
+       if ( flags & WBFLAG_ALLOCATE_RID ) {
+               if ( !NT_STATUS_IS_OK(idmap_allocate_rid(&rid, USER_RID_TYPE)) ) {
+                       DEBUG(0,("winbindd_create_user: RID allocation failure!  Cannot create user (%s)\n",
+                               user));
+                       wb_delete_user( &pw );
+                       
+                       return WINBINDD_ERROR;
+               }
+               
+               state->response.data.rid = rid;
+       }
 
-       return ( wb_storepwnam(&pw) ? WINBINDD_OK : WINBINDD_ERROR );
+       return WINBINDD_OK;
 }
 
 /**********************************************************************
@@ -794,6 +953,8 @@ enum winbindd_result winbindd_create_group(struct winbindd_cli_state *state)
        char *group;
        unid_t id;
        WINBINDD_GR grp;
+       uint32 flags = state->request.flags;
+       uint32 rid;
        
        if ( !state->privileged ) {
                DEBUG(2, ("winbindd_create_group: non-privileged access denied!\n"));
@@ -821,8 +982,25 @@ enum winbindd_result winbindd_create_group(struct winbindd_cli_state *state)
        grp.gr_gid      = id.gid;
        grp.gr_mem      = NULL; /* start with no members */
        grp.num_gr_mem  = 0;
+       
+       if ( !wb_storegrnam(&grp) )
+               return WINBINDD_ERROR;
+               
+       /* do we need a new RID? */
+       
+       if ( flags & WBFLAG_ALLOCATE_RID ) {
+               if ( !NT_STATUS_IS_OK(idmap_allocate_rid(&rid, GROUP_RID_TYPE)) ) {
+                       DEBUG(0,("winbindd_create_group: RID allocation failure!  Cannot create group (%s)\n",
+                               group));
+                       wb_delete_group( &grp );
+                       
+                       return WINBINDD_ERROR;
+               }
+               
+               state->response.data.rid = rid;
+       }
 
-       return ( wb_storegrnam(&grp) ? WINBINDD_OK : WINBINDD_ERROR );
+       return WINBINDD_OK;
 }
 
 /**********************************************************************
@@ -989,8 +1167,7 @@ enum winbindd_result winbindd_delete_user(struct winbindd_cli_state *state)
                return WINBINDD_ERROR;
        }
        
-       
-       return ( wb_delete_user(user) ? WINBINDD_OK : WINBINDD_ERROR );
+       return ( wb_delete_user(pw) ? WINBINDD_OK : WINBINDD_ERROR );
 }
 
 /**********************************************************************
@@ -1001,6 +1178,7 @@ enum winbindd_result winbindd_delete_group(struct winbindd_cli_state *state)
 {
        WINBINDD_GR *grp;
        char *group;
+       BOOL ret;
 
        if ( !state->privileged ) {
                DEBUG(2, ("winbindd_delete_group: non-privileged access denied!\n"));
@@ -1016,13 +1194,15 @@ enum winbindd_result winbindd_delete_group(struct winbindd_cli_state *state)
        /* make sure it is a valid group */
        
        if ( !(grp = wb_getgrnam( group )) ) {
-               DEBUG(4,("winbindd_delete_user: Cannot delete a non-existent group\n"));
+               DEBUG(4,("winbindd_delete_group: Cannot delete a non-existent group\n"));
                return WINBINDD_ERROR;
        }
        
+       ret = wb_delete_group(grp);
+       
        free_winbindd_gr( grp );
        
-       return ( wb_delete_group(group) ? WINBINDD_OK : WINBINDD_ERROR );
+       return ( ret ? WINBINDD_OK : WINBINDD_ERROR );
 }
 
 
index a2d9e82c7c7516ca56a2ea49ae69ca42a500df1a..c4407bbe31c9062302676cc5aad5a0fdbbef999a 100644 (file)
@@ -148,6 +148,7 @@ typedef struct winbindd_gr {
 #define WBFLAG_PAM_LMKEY               0x0008
 #define WBFLAG_PAM_CONTACT_TRUSTDOM    0x0010
 #define WBFLAG_QUERY_ONLY              0x0020
+#define WBFLAG_ALLOCATE_RID            0x0040
 
 /* Winbind request structure */
 
@@ -257,6 +258,7 @@ struct winbindd_response {
                        char nt_session_key[16];
                        char first_8_lm_hash[8];
                } auth;
+               uint32 rid;     /* create user or group */
        } data;
 
        /* Variable length return data */
index 7c95ba847050efdf66104840f50778a736b8fe92..c49c41687b9e45cfb47f083eb222ccac1660d131 100644 (file)
@@ -308,6 +308,19 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
                free_getent_state(state->getpwent_state);
                state->getpwent_state = NULL;
        }
+
+#if 0  /* JERRY */
+       /* add any local users we have */
+               
+       if ( (domain_state = (struct getent_state *)malloc(sizeof(struct getent_state))) == NULL )
+               return WINBINDD_ERROR;
+                
+       ZERO_STRUCTP(domain_state);
+
+       /* Add to list of open domains */
+                
+       DLIST_ADD(state->getpwent_state, domain_state);
+#endif
         
        /* Create sam pipes for each domain we know about */
         
index a2623ff3d703561dce437ee915c2092c08ae8e67..408695d4bd1979c8e3b80cf236530764a974afde 100644 (file)
@@ -290,41 +290,37 @@ NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
 
 /*************************************************************
  Initialises a SAM_ACCOUNT ready to add a new account, based
- on the unix user if possible.
+ on the UNIX user.  Pass in a RID if you have one
  ************************************************************/
 
-NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username)
+NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username,
+                          uint32 rid)
 {
-       NTSTATUS nt_status = NT_STATUS_NO_MEMORY;
-
-       struct passwd *pwd;
+       NTSTATUS        nt_status = NT_STATUS_NO_MEMORY;
+       struct passwd   *pwd;
+       BOOL            ret;
        
        pwd = Get_Pwnam(username);
 
-       if (pwd) {
-               if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd))) {
-                       *new_sam_acct = NULL;
-                       return nt_status;
-               }
-       } else {
-               DOM_SID g_sid;
-               if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
-                       *new_sam_acct = NULL;
-                       return nt_status;
-               }
-               if (!pdb_set_username(*new_sam_acct, username, PDB_SET)) {
-                       pdb_free_sam(new_sam_acct);
-                       return nt_status;
-               }
-
-               pdb_set_domain (*new_sam_acct, get_global_sam_name(), PDB_DEFAULT);
-
-               /* set Domain Users by default ! */
-               sid_copy(&g_sid, get_global_sam_sid());
-               sid_append_rid(&g_sid, DOMAIN_GROUP_RID_USERS);
-               pdb_set_group_sid(*new_sam_acct, &g_sid, PDB_SET);
+       if (!pwd) 
+               return NT_STATUS_NO_SUCH_USER;
+       
+       if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd))) {
+               *new_sam_acct = NULL;
+               return nt_status;
        }
-       return NT_STATUS_OK;
+       
+       /* see if we need to generate a new rid using the 2.2 algorithm */
+       if ( rid == 0 && lp_enable_rid_algorithm() ) {
+               DEBUG(10,("pdb_init_sam_new: no RID specified.  Generating one via old algorithm\n"));
+               rid = fallback_pdb_uid_to_user_rid(pwd->pw_uid);
+       }
+       
+       /* set the new SID */
+       
+       ret = pdb_set_user_sid_from_rid( *new_sam_acct, rid, PDB_SET );
+        
+       return (ret ? NT_STATUS_OK : NT_STATUS_NO_SUCH_USER);
 }
 
 
@@ -920,8 +916,8 @@ BOOL local_password_change(const char *user_name, int local_flags,
                pdb_free_sam(&sam_pass);
                
                if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
-                       /* Might not exist in /etc/passwd */
-                       if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name))) {
+                       /* Might not exist in /etc/passwd.  Use rid algorithm here */
+                       if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
                                slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
                                return False;
                        }
@@ -1247,121 +1243,6 @@ BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_
        return True;
 }
 
-/**********************************************************************
-**********************************************************************/
-
-BOOL pdb_get_free_ugid_range(uint32 *low, uint32 *high)
-{
-       uid_t u_low, u_high;
-       gid_t g_low, g_high;
-
-       if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
-               return False;
-       }
-       
-       *low  = (u_low < g_low)   ? u_low  : g_low;
-       *high = (u_high < g_high) ? u_high : g_high;
-       
-       return True;
-}
-
-/******************************************************************
- Get the the non-algorithmic RID range if idmap range are defined
-******************************************************************/
-
-BOOL pdb_get_free_rid_range(uint32 *low, uint32 *high)
-{
-       uint32 id_low, id_high;
-
-       if (!lp_enable_rid_algorithm()) {
-               *low = BASE_RID;
-               *high = (uint32)-1;
-       }
-
-       if (!pdb_get_free_ugid_range(&id_low, &id_high)) {
-               return False;
-       }
-
-       *low = fallback_pdb_uid_to_user_rid(id_low);
-       if (fallback_pdb_user_rid_to_uid((uint32)-1) < id_high) {
-               *high = (uint32)-1;
-       } else {
-               *high = fallback_pdb_uid_to_user_rid(id_high);
-       }
-
-       return True;
-}
-
-/**********************************************************************
- Get the free RID base if idmap is configured, otherwise return 0
-**********************************************************************/
-
-uint32 pdb_get_free_rid_base(void)
-{
-       uint32 low, high;
-       if (pdb_get_free_rid_range(&low, &high)) {
-               return low;
-       }
-       return 0;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-BOOL pdb_check_ugid_is_in_free_range(uint32 id)
-{
-       uint32 low, high;
-
-       if (!pdb_get_free_ugid_range(&low, &high)) {
-               return False;
-       }
-       if (id < low || id > high) {
-               return False;
-       }
-       return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-BOOL pdb_check_rid_is_in_free_range(uint32 rid)
-{
-       uint32 low, high;
-
-       if (!pdb_get_free_rid_range(&low, &high)) {
-               return False;
-       }
-       if (rid < algorithmic_rid_base()) {
-               return True;
-       }
-
-       if (rid < low || rid > high) {
-               return False;
-       }
-
-       return True;
-}
-
-/**********************************************************************
- if it is a foreign SID or if the SID is in the free range, return true
-**********************************************************************/
-
-BOOL pdb_check_sid_is_in_free_range(const DOM_SID *sid)
-{
-       if (sid_compare_domain(get_global_sam_sid(), sid) == 0) {
-       
-               uint32 rid;
-
-               if (sid_peek_rid(sid, &rid)) {
-                       return pdb_check_rid_is_in_free_range(rid);
-               }
-
-               return False;
-       }
-
-       return True;
-}
-
 /**********************************************************************
  Marshall/unmarshall SAM_ACCOUNT structs.
  *********************************************************************/
index 886fd809f32d34c8797ddff632bad64d6ad41640..e32f566a7d759efa8c88d1a5c20bf948a201721e 100644 (file)
@@ -96,15 +96,6 @@ struct ldapsam_privates {
        
        /* configuration items */
        int schema_ver;
-
-       BOOL permit_non_unix_accounts;
-       
-       uint32 low_allocated_user_rid; 
-       uint32 high_allocated_user_rid; 
-
-       uint32 low_allocated_group_rid; 
-       uint32 high_allocated_group_rid; 
-
 };
 
 /**********************************************************************
@@ -338,423 +329,7 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
        ldap_memfree(dn);
        return NT_STATUS_OK;
 }
-                                         
-/**********************************************************************
- Add the sambaDomain to LDAP, so we don't have to search for this stuff
- again.  This is a once-add operation for now.
-
- TODO:  Add other attributes, and allow modification.
-*********************************************************************/
-static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state) 
-{
-       fstring sid_string;
-       fstring algorithmic_rid_base_string;
-       pstring filter, dn;
-       LDAPMod **mods = NULL;
-       int rc;
-       int ldap_op;
-       LDAPMessage *result = NULL;
-       int num_result;
-       char **attr_list;
-
-       slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))", 
-                 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), 
-                 ldap_state->domain_name, LDAP_OBJ_DOMINFO);
-
-       attr_list = get_attr_list( dominfo_attr_list );
-       rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, 
-                                  attr_list, &result);
-       free_attr_list( attr_list );
-
-       if (rc != LDAP_SUCCESS) {
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-       
-       if (num_result > 1) {
-               DEBUG (0, ("More than domain with that name exists: bailing out!\n"));
-               ldap_msgfree(result);
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-       
-       /* Check if we need to add an entry */
-       DEBUG(3,("Adding new domain\n"));
-       ldap_op = LDAP_MOD_ADD;
-
-       snprintf(dn, sizeof(dn), "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
-               ldap_state->domain_name, lp_ldap_suffix());
-
-       /* Free original search */
-       ldap_msgfree(result);
-
-       /* make the changes - the entry *must* not already have samba attributes */
-       smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), 
-               ldap_state->domain_name);
-
-       /* If we don't have an entry, then ask secrets.tdb for what it thinks.  
-          It may choose to make it up */
-
-       sid_to_string(sid_string, get_global_sam_sid());
-       smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), sid_string);
-
-       slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string) - 1, "%i", algorithmic_rid_base());
-       smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE), 
-                       algorithmic_rid_base_string);
-       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
-
-       switch(ldap_op)
-       {
-       case LDAP_MOD_ADD: 
-               rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
-               break;
-       case LDAP_MOD_REPLACE: 
-               rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
-               break;
-       default:        
-               DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-       
-       if (rc!=LDAP_SUCCESS) {
-               char *ld_error = NULL;
-               ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
-                               &ld_error);
-               DEBUG(1,
-                     ("failed to %s domain dn= %s with: %s\n\t%s\n",
-                      ldap_op == LDAP_MOD_ADD ? "add" : "modify",
-                      dn, ldap_err2string(rc),
-                      ld_error?ld_error:"unknown"));
-               SAFE_FREE(ld_error);
-
-               ldap_mods_free(mods, True);
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       DEBUG(2,("added: domain = %s in the LDAP database\n", ldap_state->domain_name));
-       ldap_mods_free(mods, True);
-       return NT_STATUS_OK;
-}
-
-/**********************************************************************
-Search for the domain info entry
-*********************************************************************/
-static NTSTATUS ldapsam_search_domain_info(struct ldapsam_privates *ldap_state,
-                                          LDAPMessage ** result, BOOL try_add)
-{
-       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-       pstring filter;
-       int rc;
-       char **attr_list;
-       int count;
-
-       snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
-               LDAP_OBJ_DOMINFO,
-               get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), 
-               ldap_state->domain_name);
-
-       DEBUG(2, ("Searching for:[%s]\n", filter));
-
-
-       attr_list = get_attr_list( dominfo_attr_list );
-       rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, 
-                                  attr_list , result);
-       free_attr_list( attr_list );
-
-       if (rc != LDAP_SUCCESS) {
-               DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc)));
-               DEBUG(2,("Query was: %s, %s\n", lp_ldap_suffix(), filter));
-       } else if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, *result) < 1) {
-               DEBUG(3, ("Got no domain info entries for domain %s\n",
-                         ldap_state->domain_name));
-               ldap_msgfree(*result);
-               *result = NULL;
-               if (try_add && NT_STATUS_IS_OK(ret = add_new_domain_info(ldap_state))) {
-                       return ldapsam_search_domain_info(ldap_state, result, False);
-               } else {
-                       DEBUG(0, ("Adding domain info failed with %s\n", nt_errstr(ret)));
-                       return ret;
-               }
-       } else if ((count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, *result)) > 1) {
-               DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n",
-                         count, ldap_state->domain_name));
-               ldap_msgfree(*result);
-               *result = NULL;
-               return ret;
-       } else {
-               return NT_STATUS_OK;
-       }
-       
-       return ret;
-}
-
-/**********************************************************************
- Even if the sambaDomain attribute in LDAP tells us that this RID is 
- safe to use, always check before use.  
-*********************************************************************/
-static BOOL sid_in_use(struct ldapsam_privates *ldap_state, 
-                      const DOM_SID *sid, int *error) 
-{
-       fstring filter;
-       fstring sid_string;
-       LDAPMessage *result = NULL;
-       int count;
-       int rc;
-       char *sid_attr[] = {LDAP_ATTRIBUTE_SID, NULL};
-
-       slprintf(filter, sizeof(filter)-1, "(%s=%s)", LDAP_ATTRIBUTE_SID, sid_to_string(sid_string, sid));
-
-       rc = smbldap_search_suffix(ldap_state->smbldap_state, 
-                                  filter, sid_attr, &result);
-
-       if (rc != LDAP_SUCCESS) {
-               char *ld_error = NULL;
-               ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
-               DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n", 
-                         sid_string, ld_error));
-               SAFE_FREE(ld_error);
-
-               *error = rc;
-               return True;
-       }
-       
-       if ((count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result)) > 0) {
-               DEBUG(3, ("Sid %s already in use - trying next RID\n",
-                         sid_string));
-               ldap_msgfree(result);
-               return True;
-       }
-
-       ldap_msgfree(result);
-
-       /* good, sid is not in use */
-       return False;
-}
-
-/**********************************************************************
- Set the new nextRid attribute, and return one we can use.
-
- This also checks that this RID is actually free - in case the admin
- manually stole it :-).
-*********************************************************************/
-static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *rid, int rid_type)
-{
-       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-       int rc;
-       LDAPMessage *domain_result = NULL;
-       LDAPMessage *entry  = NULL;
-       char *dn;
-       LDAPMod **mods = NULL;
-       fstring old_rid_string;
-       fstring next_rid_string;
-       fstring algorithmic_rid_base_string;
-       uint32 next_rid;
-       uint32 alg_rid_base;
-       int attempts = 0;
-       char *ld_error = NULL;
-
-       if ( ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT ) {
-               DEBUG(0, ("Allocated RIDs require the %s objectclass used by 'ldapsam'\n", 
-                       LDAP_OBJ_SAMBASAMACCOUNT));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-       
-       while (attempts < 10) 
-       {
-               if (!NT_STATUS_IS_OK(ret = ldapsam_search_domain_info(ldap_state, &domain_result, True))) {
-                       return ret;
-               }
-       
-               entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, domain_result);
-               if (!entry) {
-                       DEBUG(0, ("Could not get domain info entry\n"));
-                       ldap_msgfree(domain_result);
-                       return ret;
-               }
-
-               if ((dn = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry)) == NULL) {
-                       DEBUG(0, ("Could not get domain info DN\n"));
-                       ldap_msgfree(domain_result);
-                       return ret;
-               }
-
-               /* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and 
-                  algorithmic_rid_base.  The other two are to avoid stomping on the 
-                  different sets of algorithmic RIDs */
-               
-               if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
-                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
-                                        algorithmic_rid_base_string)) 
-               {
-                       
-                       alg_rid_base = (uint32)atol(algorithmic_rid_base_string);
-               } else {
-                       alg_rid_base = algorithmic_rid_base();
-                       /* Try to make the modification atomically by enforcing the
-                          old value in the delete mod. */
-                       slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string)-1, "%d", alg_rid_base);
-                       smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, 
-                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE), 
-                                        algorithmic_rid_base_string);
-               }
-
-               next_rid = 0;
-
-               if (alg_rid_base > BASE_RID) {
-                       /* we have a non-default 'algorithmic rid base', so we have 'low' rids that we 
-                          can allocate to new users */
-                       if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
-                                                get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_RID),
-                                                old_rid_string)) 
-                       {
-                               *rid = (uint32)atol(old_rid_string);
-                       } else {
-                               *rid = BASE_RID;
-                       }
-
-                       next_rid = *rid+1;
-                       if (next_rid >= alg_rid_base) {
-                               return NT_STATUS_UNSUCCESSFUL;
-                       }
-                       
-                       slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
-                               
-                       /* Try to make the modification atomically by enforcing the
-                          old value in the delete mod. */
-                       smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, 
-                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_RID), 
-                                        next_rid_string);
-               }
-
-               if (!next_rid) { /* not got one already */
-                       switch (rid_type) {
-                       case USER_RID_TYPE:
-                               if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
-                                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
-                                                        old_rid_string)) 
-                               {
-                                       
-                                       *rid = (uint32)atol(old_rid_string);
-                                       
-                               } else {
-                                       *rid = ldap_state->low_allocated_user_rid;
-                               }
-                               break;
-                       case GROUP_RID_TYPE:
-                               if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, 
-                                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
-                                                        old_rid_string)) 
-                               {
-                                       *rid = (uint32)atol(old_rid_string);
-                               } else {
-                                       *rid = ldap_state->low_allocated_group_rid;
-                               }
-                               break;
-                       }
-                       
-                       /* This is the core of the whole routine. If we had
-                          scheme-style closures, there would be a *lot* less code
-                          duplication... */
-
-                       next_rid = *rid+RID_MULTIPLIER;
-                       slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
-                       
-                       switch (rid_type) {
-                       case USER_RID_TYPE:
-                               if (next_rid > ldap_state->high_allocated_user_rid) {
-                                       return NT_STATUS_UNSUCCESSFUL;
-                               }
-                               
-                               /* Try to make the modification atomically by enforcing the
-                                  old value in the delete mod. */
-                               smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, 
-                                                get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), 
-                                                next_rid_string);
-                               break;
-                               
-                       case GROUP_RID_TYPE:
-                               if (next_rid > ldap_state->high_allocated_group_rid) {
-                                       return NT_STATUS_UNSUCCESSFUL;
-                               }
-                               
-                               /* Try to make the modification atomically by enforcing the
-                                  old value in the delete mod. */
-                               smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods,
-                                                get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
-                                                next_rid_string);
-                               break;
-                       }
-               }
-
-               if ((rc = ldap_modify_s(ldap_state->smbldap_state->ldap_struct, dn, mods)) == LDAP_SUCCESS) {
-                       DOM_SID dom_sid;
-                       DOM_SID sid;
-                       pstring domain_sid_string;
-                       int error = 0;
-
-                       if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, domain_result,
-                               get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID),
-                               domain_sid_string)) 
-                       {
-                               ldap_mods_free(mods, True);
-                               ldap_memfree(dn);
-                               ldap_msgfree(domain_result);
-                               return ret;
-                       }
-
-                       if (!string_to_sid(&dom_sid, domain_sid_string)) { 
-                               ldap_mods_free(mods, True);
-                               ldap_memfree(dn);
-                               ldap_msgfree(domain_result);
-                               return ret;
-                       }
-
-                       ldap_mods_free(mods, True);
-                       mods = NULL;
-                       ldap_memfree(dn);
-                       ldap_msgfree(domain_result);
-
-                       sid_copy(&sid, &dom_sid);
-                       sid_append_rid(&sid, *rid);
-
-                       /* check RID is not in use */
-                       if (sid_in_use(ldap_state, &sid, &error)) {
-                               if (error) {
-                                       return ret;
-                               }
-                               continue;
-                       }
-
-                       return NT_STATUS_OK;
-               }
-
-               ld_error = NULL;
-               ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
-               DEBUG(2, ("Failed to modify rid: %s\n", ld_error ? ld_error : "(NULL"));
-               SAFE_FREE(ld_error);
-
-               ldap_mods_free(mods, True);
-               mods = NULL;
-
-               ldap_memfree(dn);
-               dn = NULL;
-
-               ldap_msgfree(domain_result);
-               domain_result = NULL;
-
-               {
-                       /* Sleep for a random timeout */
-                       unsigned sleeptime = (sys_random()*sys_getpid()*attempts);
-                       attempts += 1;
-                       
-                       sleeptime %= 100;
-                       msleep(sleeptime);
-               }
-       }
-
-       DEBUG(0, ("Failed to set new RID\n"));
-       return ret;
-}
+                 
 
 /* New Interface is being implemented here */
 
@@ -1192,34 +767,6 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
 
        DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
 
-       if (pdb_get_init_flags(sampass, PDB_USERSID) == PDB_DEFAULT) {
-               if (ldap_state->permit_non_unix_accounts) {
-                       if (!NT_STATUS_IS_OK(ldapsam_next_rid(ldap_state, &rid, USER_RID_TYPE))) {
-                               DEBUG(0, ("NO user RID specified on account %s, and "
-                                         "finding next available NUA RID failed, "
-                                         "cannot store!\n",
-                                         pdb_get_username(sampass)));
-                               ldap_mods_free(*mods, True);
-                               return False;
-                       }
-               } else {
-                       DEBUG(0, ("NO user RID specified on account %s, "
-                                 "cannot store!\n", pdb_get_username(sampass)));
-                       ldap_mods_free(*mods, True);
-                       return False;
-               }
-
-               /* now that we have figured out the RID, always store it, as
-                  the schema requires it (either as a SID or a RID) */
-                  
-               if (!pdb_set_user_sid_from_rid(sampass, rid, PDB_CHANGED)) {
-                       DEBUG(0, ("Could not store RID back onto SAM_ACCOUNT for user %s!\n", 
-                                 pdb_get_username(sampass)));
-                       ldap_mods_free(*mods, True);
-                       return False;
-               }
-       }
-
        /* only update the RID if we actually need to */
        if (need_update(sampass, PDB_USERSID)) 
        {
@@ -2733,10 +2280,8 @@ static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_met
        struct ldapsam_privates *ldap_state;
        uint32 alg_rid_base;
        pstring alg_rid_base_string;
-       uint32 low_idmap_uid, high_idmap_uid;
-       uint32 low_idmap_gid, high_idmap_gid;
-       LDAPMessage *result;
-       LDAPMessage *entry;
+       LDAPMessage *result = NULL;
+       LDAPMessage *entry = NULL;
        DOM_SID ldap_domain_sid;
        DOM_SID secrets_domain_sid;
        pstring domain_sid_string;
@@ -2748,14 +2293,17 @@ static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_met
        (*pdb_method)->name = "ldapsam";
 
        ldap_state = (*pdb_method)->private_data;
-       ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;     
-       ldap_state->permit_non_unix_accounts = False;
+       ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
 
        /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
-
-       if (!NT_STATUS_IS_OK(nt_status = ldapsam_search_domain_info(ldap_state, &result, True))) {
+       
+       nt_status = smbldap_search_domain_info(ldap_state->smbldap_state, &result, 
+               ldap_state->domain_name, True);
+       
+       if ( !NT_STATUS_IS_OK(nt_status) ) {
                DEBUG(2, ("WARNING: Could not get domain info, nor add one to the domain\n"));
-               DEBUGADD(2, ("Continuing on regardless, will be unable to allocate new users/groups, and will risk BDCs having inconsistant SIDs\n"));
+               DEBUGADD(2, ("Continuing on regardless, will be unable to allocate new users/groups, "
+                       "and will risk BDCs having inconsistant SIDs\n"));
                sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
                return NT_STATUS_OK;
        }
@@ -2796,21 +2344,6 @@ static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_met
                }
        }
        ldap_msgfree(result);
-       
-       /* check for non-unix account ranges */
-
-       if (lp_idmap_uid(&low_idmap_uid, &high_idmap_uid) 
-               &&  lp_idmap_gid(&low_idmap_gid, &high_idmap_gid)) 
-       {
-               DEBUG(2, ("Enabling non-unix account ranges\n"));
-
-               ldap_state->permit_non_unix_accounts = True;
-
-               ldap_state->low_allocated_user_rid   = fallback_pdb_uid_to_user_rid(low_idmap_uid);
-               ldap_state->high_allocated_user_rid  = fallback_pdb_uid_to_user_rid(high_idmap_uid);
-               ldap_state->low_allocated_group_rid  = pdb_gid_to_group_rid(low_idmap_gid);
-               ldap_state->high_allocated_group_rid = pdb_gid_to_group_rid(high_idmap_gid);
-       }
 
        return NT_STATUS_OK;
 }
index 0e7dd77b405c5c5dec056287cca8a0db7e115efc..055e8e71bac241a5d14656a4de71c6fd57f31482 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * Unix SMB/CIFS implementation. 
  * SMB parameters and setup
- * Copyright (C) Andrew Tridgell 1992-1998 
- * Modified by Jeremy Allison 1995.
- * Modified by Gerald (Jerry) Carter 2000-2001
- * Modified by Andrew Bartlett 2002.
+ * Copyright (C) Andrew Tridgell       1992-1998 
+ * Modified by Jeremy Allison          1995.
+ * Modified by Gerald (Jerry) Carter   2000-2001,2003
+ * Modified by Andrew Bartlett         2002.
  * 
  * 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
  
 struct smb_passwd
 {
-        BOOL smb_userid_set;     /* this is actually the unix uid_t */
-        uint32 smb_userid;     /* this is actually the unix uid_t */
+        uint32 smb_userid;        /* this is actually the unix uid_t */
         const char *smb_name;     /* username string */
 
-        const unsigned char *smb_passwd; /* Null if no password */
+        const unsigned char *smb_passwd;    /* Null if no password */
         const unsigned char *smb_nt_passwd; /* Null if no password */
 
-        uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
+        uint16 acct_ctrl;             /* account info (ACB_xxxx bit-mask) */
         time_t pass_last_set_time;    /* password last set time */
 };
 
@@ -61,12 +60,6 @@ struct smbpasswd_privates
 
        /* retrive-once info */
        const char *smbpasswd_file;
-
-       BOOL permit_non_unix_accounts;
-
-       uid_t low_nua_userid; 
-       uid_t high_nua_userid; 
-
 };
 
 enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE };
@@ -591,28 +584,6 @@ static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, str
 
   /* Ok - entry doesn't exist. We can add it */
 
-  /* Account not in /etc/passwd hack!!! */
-  if (!newpwd->smb_userid_set) {
-         if (!smbpasswd_state->permit_non_unix_accounts) {
-                 DEBUG(0, ("add_smbfilepwd_entry: cannot add account %s without unix identity\n", newpwd->smb_name));
-                 endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
-                 return False;
-         }
-
-         if (max_found_uid < smbpasswd_state->low_nua_userid) {
-                 newpwd->smb_userid = smbpasswd_state->low_nua_userid;
-                 newpwd->smb_userid_set = True;
-         } else if (max_found_uid >= smbpasswd_state->high_nua_userid) {
-                 DEBUG(0, ("add_smbfilepwd_entry: cannot add machine %s, no uids are free! \n", newpwd->smb_name));
-                 endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
-                 return False;           
-         } else {
-                 newpwd->smb_userid = max_found_uid + 1;
-                 newpwd->smb_userid_set = True;
-         }
-  }
-
-
   /* Create a new smb passwd entry and set it to the given password. */
   /* 
    * The add user write needs to be atomic - so get the fd from 
@@ -1149,12 +1120,10 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
                                DEBUG(0, ("Could not find gest account via getpwnam()! (%s)\n", lp_guestaccount()));
                                return False;
                        }
-                       smb_pw->smb_userid_set = True;
                        smb_pw->smb_userid=passwd->pw_uid;
                        passwd_free(&passwd);
 
                } else if (fallback_pdb_rid_is_user(rid)) {
-                       smb_pw->smb_userid_set = True;
                        smb_pw->smb_userid=fallback_pdb_user_rid_to_uid(rid);
                } else {
                        DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
@@ -1170,25 +1139,6 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
        smb_pw->acct_ctrl=pdb_get_acct_ctrl(sampass);
        smb_pw->pass_last_set_time=pdb_get_pass_last_set_time(sampass);
 
-#if 0
-       /*
-        * ifdef'out by JFM on 11/29/2001.
-        * this assertion is no longer valid
-        * and I don't understand the goal 
-        * and doing the same thing with the group mapping code
-        * is hairy !
-        *
-        * We just have the RID, in which SID is it valid ?
-        * our domain SID ? well known SID ? local SID ?
-        */
-
-       if (gid != pdb_group_rid_to_gid(pdb_get_group_rid(sampass))) {
-               DEBUG(0,("build_sam_pass: Failing attempt to store user with non-gid based primary group RID. \n"));
-               DEBUG(0,("build_sam_pass: %d %d %d. \n", *gid, pdb_group_rid_to_gid(pdb_get_group_rid(sampass)), pdb_get_group_rid(sampass)));
-               return False;
-       }
-#endif
-
        return True;
 }      
 
@@ -1204,49 +1154,28 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
                DEBUG(5,("build_sam_account: SAM_ACCOUNT is NULL\n"));
                return False;
        }
-               
-       pwfile = getpwnam_alloc(pw_buf->smb_name);
-       if (pwfile == NULL) {
-               if ((smbpasswd_state->permit_non_unix_accounts) 
-                   && (pw_buf->smb_userid >= smbpasswd_state->low_nua_userid) 
-                   && (pw_buf->smb_userid <= smbpasswd_state->high_nua_userid)) {
 
-                       pdb_set_user_sid_from_rid(sam_pass, fallback_pdb_uid_to_user_rid (pw_buf->smb_userid), PDB_SET);
-                       
-                       /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. 
-                          
-                       This was down the bottom for machines, but it looks pretty good as
-                       a general default for non-unix users. --abartlet 2002-01-08
-                       */
-                       pdb_set_group_sid_from_rid (sam_pass, DOMAIN_GROUP_RID_USERS, PDB_SET); 
-                       pdb_set_username (sam_pass, pw_buf->smb_name, PDB_SET);
-                       pdb_set_domain (sam_pass, get_global_sam_name(), PDB_DEFAULT);
+       /* verify the user account exists */
                        
-               } else {
-                       DEBUG(0,("build_sam_account: smbpasswd database is corrupt!  username %s with uid %u is not in unix passwd database!\n", pw_buf->smb_name, pw_buf->smb_userid));
-                       return False;
-               }
-       } else {
-               if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile))) {
+       if ( !(pwfile = getpwnam_alloc(pw_buf->smb_name)) ) {
+               DEBUG(0,("build_sam_account: smbpasswd database is corrupt!  username %s with uid "
+               "%u is not in unix passwd database!\n", pw_buf->smb_name, pw_buf->smb_userid));
                        return False;
-               }
-               
-               passwd_free(&pwfile);
        }
        
+       if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile)))
+               return False;
+               
+       passwd_free(&pwfile);
+
+       /* set remaining fields */
+               
        pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd, PDB_SET);
        pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd, PDB_SET);                  
        pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl, PDB_SET);
        pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET);
        pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET);
        
-#if 0  /* JERRY */
-       /* the smbpasswd format doesn't have a must change time field, so
-          we can't get this right. The best we can do is to set this to 
-          some time in the future. 21 days seems as reasonable as any other value :) 
-       */
-       pdb_set_pass_must_change_time (sam_pass, pw_buf->pass_last_set_time + MAX_PASSWORD_AGE, PDB_DEFAULT);
-#endif
        return True;
 }
 
@@ -1558,11 +1487,6 @@ static NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_m
 
        (*pdb_method)->free_private_data = free_private_data;
 
-       if (lp_idmap_uid(&privates->low_nua_userid, &privates->high_nua_userid)) {
-               DEBUG(3, ("idmap uid range defined, non unix accounts enabled\n"));
-               privates->permit_non_unix_accounts = True;
-       }
-
        return NT_STATUS_OK;
 }
 
index a166697b4bcf3bc6d432c6d21a411e33c28d95df..6f5d348ce1324e7a7764493397834ea32eda44c2 100644 (file)
@@ -1,11 +1,11 @@
 /*
  * Unix SMB/CIFS implementation. 
  * SMB parameters and setup
- * Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Simo Sorce 2000-2002
- * Copyright (C) Gerald Carter 2000
- * Copyright (C) Jeremy Allison 2001
- * Copyright (C) Andrew Bartlett 2002
+ * Copyright (C) Andrew Tridgell   1992-1998
+ * Copyright (C) Simo Sorce        2000-2002
+ * Copyright (C) Gerald Carter     2000
+ * Copyright (C) Jeremy Allison    2001
+ * Copyright (C) Andrew Bartlett   2002
  * 
  * 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
@@ -48,13 +48,6 @@ struct tdbsam_privates {
 
        /* retrive-once info */
        const char *tdbsam_location;
-
-       BOOL permit_non_unix_accounts;
-
-       BOOL algorithmic_rids;
-
-       uint32 low_nua_rid; 
-       uint32 high_nua_rid;
 };
 
 /***************************************************************
@@ -342,61 +335,31 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd,
        fstring         name;
        BOOL            ret = True;
        uint32          user_rid;
-       BOOL            tdb_ret;
 
        /* invalidate the existing TDB iterator if it is open */
+       
        if (tdb_state->passwd_tdb) {
                tdb_close(tdb_state->passwd_tdb);
                tdb_state->passwd_tdb = NULL;
        }
 
        /* open the account TDB passwd*/
+       
        pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
-       if (!pwd_tdb)
-       {
-               DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location));
+       
+       if (!pwd_tdb) {
+               DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", 
+                       tdb_state->tdbsam_location));
                return False;
        }
 
        if (!pdb_get_group_rid(newpwd)) {
-               DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd)));
+               DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",
+                       pdb_get_username(newpwd)));
                ret = False;
                goto done;
        }
 
-       /* if flag == TDB_INSERT then make up a new RID else throw an error. */
-       if (!(user_rid = pdb_get_user_rid(newpwd))) {
-               if ((flag & TDB_INSERT) && tdb_state->permit_non_unix_accounts) {
-                       uint32 lowrid, highrid;
-                       if (!pdb_get_free_rid_range(&lowrid, &highrid)) {
-                               /* should never happen */
-                               DEBUG(0, ("tdbsam: something messed up, no high/low rids but nua enabled ?!\n"));
-                               ret = False;
-                               goto done;
-                       }
-                       user_rid = lowrid;
-                       tdb_ret = tdb_change_uint32_atomic(pwd_tdb, "RID_COUNTER", &user_rid, RID_MULTIPLIER);
-                       if (!tdb_ret) {
-                               ret = False;
-                               goto done;
-                       }
-                       if (user_rid > highrid) {
-                               DEBUG(0, ("tdbsam: no NUA rids available, cannot add user %s!\n", pdb_get_username(newpwd)));
-                               ret = False;
-                               goto done;
-                       }
-                       if (!pdb_set_user_sid_from_rid(newpwd, user_rid, PDB_CHANGED)) {
-                               DEBUG(0, ("tdbsam: not able to set new allocated user RID into sam account!\n"));
-                               ret = False;
-                               goto done;
-                       }
-               } else {
-                       DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a RID\n",pdb_get_username(newpwd)));
-                       ret = False;
-                       goto done;
-               }
-       }
-
        /* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */
        if ((data.dsize=init_buffer_from_sam (&buf, newpwd, False)) == -1) {
                DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n"));
@@ -531,7 +494,6 @@ static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_meth
 {
        NTSTATUS nt_status;
        struct tdbsam_privates *tdb_state;
-       uid_t low_nua_uid, high_nua_uid;
 
        if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
                return nt_status;
@@ -569,19 +531,6 @@ static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_meth
 
        (*pdb_method)->free_private_data = free_private_data;
 
-       if (lp_idmap_uid(&low_nua_uid, &high_nua_uid)) {
-               DEBUG(3, ("idmap uid range defined, non unix accounts enabled\n"));
-
-               tdb_state->permit_non_unix_accounts = True;
-
-               tdb_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
-
-               tdb_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
-
-       } else {
-               tdb_state->algorithmic_rids = True;
-       }
-
        return NT_STATUS_OK;
 }
 
index dfa3a8b62e096d88bd05d8a6a325f7423857a884..9324fd4765a95c5efa7bb59478fc762633ea0f70 100644 (file)
@@ -2204,6 +2204,7 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
        uint32 acc_granted;
        SEC_DESC *psd;
        size_t    sd_size;
+       uint32 new_rid = 0;
        /* check this, when giving away 'add computer to domain' privs */
        uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
 
@@ -2272,6 +2273,17 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
           
        pw = Get_Pwnam(account);
        
+       /*********************************************************************
+        * 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 
+        * backend. It has been moved into idmap now.  Since idmap is now 
+        * wrapped up behind winbind, this means you have to run winbindd if you
+        * want new accounts to get a new RID when "enable rid algorithm = no".
+        * Tough.  We now have a uniform way of allocating RIDs regardless
+        * of what ever passdb backend people may use.
+        *                                             --jerry (2003-07-10)
+        *********************************************************************/
+       
        if ( !pw ) {
                /* 
                 * we can't check both the ending $ and the acb_info.
@@ -2293,15 +2305,17 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
                }
                else    /* no add user script -- ask winbindd to do it */
                {
-                       if ( !winbind_create_user( account ) )
-                               DEBUG(3,("_api_samr_create_user: winbind_create_user(%s) failed\n", account));
+                       if ( !winbind_create_user( account, &new_rid ) ) {
+                               DEBUG(3,("_api_samr_create_user: winbind_create_user(%s) failed\n", 
+                                       account));
+                       }
                }
                
        }
        
-       /* implicit call to getpwnam() next */
+       /* implicit call to getpwnam() next.  we have a valid SID coming out of this call */
 
-       if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account)) )
+       if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
                return nt_status;
                
        pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
@@ -3711,12 +3725,25 @@ static int smb_delete_user(const char *unix_user)
        pstring del_script;
        int ret;
 
+       /* try winbindd first since it is impossible to determine where 
+          a user came from via NSS.  Try the delete user script if this fails
+          meaning the user did not exist in winbindd's list of accounts */
+
+       if ( winbind_delete_user( unix_user ) ) {
+               DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
+               return 0;
+       }
+
+
+       /* fall back to 'delete user script' */
+
        pstrcpy(del_script, lp_deluser_script());
        if (! *del_script)
                return -1;
        all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
        ret = smbrun(del_script,NULL);
        DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
+
        return ret;
 }
 
index 1db89eba24fef79a95bd82c0aa78159842637954..7a8f270e15a08efac5bb8dec30b5dc97d15f2546 100644 (file)
@@ -252,7 +252,7 @@ NTSTATUS idmap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
 }
 
 /**************************************************************************
- Get ID from SID. This can create a mapping for a SID to a POSIX id.
+ Alloocate a new UNIX uid/gid
 **************************************************************************/
 
 NTSTATUS idmap_allocate_id(unid_t *id, int id_type)
@@ -265,6 +265,19 @@ NTSTATUS idmap_allocate_id(unid_t *id, int id_type)
        return cache_map->allocate_id( id, id_type );
 }
 
+/**************************************************************************
+ Alloocate a new RID
+**************************************************************************/
+
+NTSTATUS idmap_allocate_rid(uint32 *rid, int type)
+{
+       /* we have to allocate from the authoritative backend */
+       
+       if ( remote_map )
+               return remote_map->allocate_rid( rid, type );
+
+       return cache_map->allocate_rid( rid, type );
+}
 
 /**************************************************************************
  Shutdown maps.
index 2901b1fc4995b419a64f05f99dc143d315ce0a75..9a1ee039d0c8f876551992483f6c82b3325d07b8 100644 (file)
@@ -42,7 +42,11 @@ struct ldap_idmap_state {
        struct smbldap_state *smbldap_state;
        TALLOC_CTX *mem_ctx;
 
-       /* struct ldap_idmap_state *prev, *next; */
+       uint32 low_allocated_user_rid;
+       uint32 high_allocated_user_rid;
+       uint32 low_allocated_group_rid;
+       uint32 high_allocated_group_rid;
+
 };
 
 #define LDAP_MAX_ALLOC_ID 128              /* number tries while allocating
@@ -56,6 +60,282 @@ static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id, int id
 static NTSTATUS ldap_idmap_close(void);
 
 
+/**********************************************************************
+ Even if the sambaDomain attribute in LDAP tells us that this RID is 
+ safe to use, always check before use.  
+*********************************************************************/
+
+static BOOL sid_in_use(struct ldap_idmap_state *state, 
+                      const DOM_SID *sid, int *error) 
+{
+       fstring filter;
+       fstring sid_string;
+       LDAPMessage *result = NULL;
+       int count;
+       int rc;
+       char *sid_attr[] = {LDAP_ATTRIBUTE_SID, NULL};
+
+       slprintf(filter, sizeof(filter)-1, "(%s=%s)", LDAP_ATTRIBUTE_SID, sid_to_string(sid_string, sid));
+
+       rc = smbldap_search_suffix(state->smbldap_state, 
+                                  filter, sid_attr, &result);
+
+       if (rc != LDAP_SUCCESS) {
+               char *ld_error = NULL;
+               ldap_get_option(state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+               DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n", 
+                         sid_string, ld_error));
+               SAFE_FREE(ld_error);
+
+               *error = rc;
+               return True;
+       }
+       
+       if ((count = ldap_count_entries(state->smbldap_state->ldap_struct, result)) > 0) {
+               DEBUG(3, ("Sid %s already in use - trying next RID\n",
+                         sid_string));
+               ldap_msgfree(result);
+               return True;
+       }
+
+       ldap_msgfree(result);
+
+       /* good, sid is not in use */
+       return False;
+}
+
+/**********************************************************************
+ Set the new nextRid attribute, and return one we can use.
+
+ This also checks that this RID is actually free - in case the admin
+ manually stole it :-).
+*********************************************************************/
+static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, 
+                              int rid_type)
+{
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+       int rc;
+       LDAPMessage *domain_result = NULL;
+       LDAPMessage *entry  = NULL;
+       char *dn;
+       LDAPMod **mods = NULL;
+       fstring old_rid_string;
+       fstring next_rid_string;
+       fstring algorithmic_rid_base_string;
+       uint32 next_rid;
+       uint32 alg_rid_base;
+       int attempts = 0;
+       char *ld_error = NULL;
+
+       while (attempts < 10) 
+       {
+               if (!NT_STATUS_IS_OK(ret = smbldap_search_domain_info(state->smbldap_state, 
+                       &domain_result, get_global_sam_name(), True))) 
+               {
+                       return ret;
+               }
+       
+               entry = ldap_first_entry(state->smbldap_state->ldap_struct, domain_result);
+               if (!entry) {
+                       DEBUG(0, ("Could not get domain info entry\n"));
+                       ldap_msgfree(domain_result);
+                       return ret;
+               }
+
+               if ((dn = ldap_get_dn(state->smbldap_state->ldap_struct, entry)) == NULL) {
+                       DEBUG(0, ("Could not get domain info DN\n"));
+                       ldap_msgfree(domain_result);
+                       return ret;
+               }
+
+               /* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and 
+                  algorithmic_rid_base.  The other two are to avoid stomping on the 
+                  different sets of algorithmic RIDs */
+               
+               if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry,
+                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
+                                        algorithmic_rid_base_string)) 
+               {
+                       
+                       alg_rid_base = (uint32)atol(algorithmic_rid_base_string);
+               } else {
+                       alg_rid_base = algorithmic_rid_base();
+                       /* Try to make the modification atomically by enforcing the
+                          old value in the delete mod. */
+                       slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string)-1, "%d", alg_rid_base);
+                       smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods, 
+                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE), 
+                                        algorithmic_rid_base_string);
+               }
+
+               next_rid = 0;
+
+               if (alg_rid_base > BASE_RID) {
+                       /* we have a non-default 'algorithmic rid base', so we have 'low' rids that we 
+                          can allocate to new users */
+                       if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry,
+                                                get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_RID),
+                                                old_rid_string)) 
+                       {
+                               *rid = (uint32)atol(old_rid_string);
+                       } else {
+                               *rid = BASE_RID;
+                       }
+
+                       next_rid = *rid+1;
+                       if (next_rid >= alg_rid_base) {
+                               return NT_STATUS_UNSUCCESSFUL;
+                       }
+                       
+                       slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
+                               
+                       /* Try to make the modification atomically by enforcing the
+                          old value in the delete mod. */
+                       smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods, 
+                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_RID), 
+                                        next_rid_string);
+               }
+
+               if (!next_rid) { /* not got one already */
+                       switch (rid_type) {
+                       case USER_RID_TYPE:
+                               if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry,
+                                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
+                                                        old_rid_string)) 
+                               {
+                                       
+                                       *rid = (uint32)atol(old_rid_string);
+                                       
+                               } else {
+                                       *rid = state->low_allocated_user_rid;
+                               }
+                               break;
+                       case GROUP_RID_TYPE:
+                               if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry, 
+                                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
+                                                        old_rid_string)) 
+                               {
+                                       *rid = (uint32)atol(old_rid_string);
+                               } else {
+                                       *rid = state->low_allocated_group_rid;
+                               }
+                               break;
+                       }
+                       
+                       /* This is the core of the whole routine. If we had
+                          scheme-style closures, there would be a *lot* less code
+                          duplication... */
+
+                       next_rid = *rid+RID_MULTIPLIER;
+                       slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
+                       
+                       switch (rid_type) {
+                       case USER_RID_TYPE:
+                               if (next_rid > state->high_allocated_user_rid) {
+                                       return NT_STATUS_UNSUCCESSFUL;
+                               }
+                               
+                               /* Try to make the modification atomically by enforcing the
+                                  old value in the delete mod. */
+                               smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods, 
+                                                get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), 
+                                                next_rid_string);
+                               break;
+                               
+                       case GROUP_RID_TYPE:
+                               if (next_rid > state->high_allocated_group_rid) {
+                                       return NT_STATUS_UNSUCCESSFUL;
+                               }
+                               
+                               /* Try to make the modification atomically by enforcing the
+                                  old value in the delete mod. */
+                               smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods,
+                                                get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
+                                                next_rid_string);
+                               break;
+                       }
+               }
+
+               if ((rc = ldap_modify_s(state->smbldap_state->ldap_struct, dn, mods)) == LDAP_SUCCESS) {
+                       DOM_SID dom_sid;
+                       DOM_SID sid;
+                       pstring domain_sid_string;
+                       int error = 0;
+
+                       if (!smbldap_get_single_attribute(state->smbldap_state->ldap_struct, domain_result,
+                               get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID),
+                               domain_sid_string)) 
+                       {
+                               ldap_mods_free(mods, True);
+                               ldap_memfree(dn);
+                               ldap_msgfree(domain_result);
+                               return ret;
+                       }
+
+                       if (!string_to_sid(&dom_sid, domain_sid_string)) { 
+                               ldap_mods_free(mods, True);
+                               ldap_memfree(dn);
+                               ldap_msgfree(domain_result);
+                               return ret;
+                       }
+
+                       ldap_mods_free(mods, True);
+                       mods = NULL;
+                       ldap_memfree(dn);
+                       ldap_msgfree(domain_result);
+
+                       sid_copy(&sid, &dom_sid);
+                       sid_append_rid(&sid, *rid);
+
+                       /* check RID is not in use */
+                       if (sid_in_use(state, &sid, &error)) {
+                               if (error) {
+                                       return ret;
+                               }
+                               continue;
+                       }
+
+                       return NT_STATUS_OK;
+               }
+
+               ld_error = NULL;
+               ldap_get_option(state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+               DEBUG(2, ("Failed to modify rid: %s\n", ld_error ? ld_error : "(NULL"));
+               SAFE_FREE(ld_error);
+
+               ldap_mods_free(mods, True);
+               mods = NULL;
+
+               ldap_memfree(dn);
+               dn = NULL;
+
+               ldap_msgfree(domain_result);
+               domain_result = NULL;
+
+               {
+                       /* Sleep for a random timeout */
+                       unsigned sleeptime = (sys_random()*sys_getpid()*attempts);
+                       attempts += 1;
+                       
+                       sleeptime %= 100;
+                       msleep(sleeptime);
+               }
+       }
+
+       DEBUG(0, ("Failed to set new RID\n"));
+       return ret;
+}
+
+
+/*****************************************************************************
+ Allocate a new RID
+*****************************************************************************/
+
+static NTSTATUS ldap_allocate_rid(uint32 *rid, int rid_type)
+{
+       return ldap_next_rid( &ldap_state, rid, rid_type );
+}
+
 /*****************************************************************************
  Allocate a new uid or gid
 *****************************************************************************/
@@ -675,6 +955,7 @@ static void ldap_idmap_status(void)
 
 static struct idmap_methods ldap_methods = {
        ldap_idmap_init,
+       ldap_allocate_rid,
        ldap_allocate_id,
        ldap_get_sid_from_id,
        ldap_get_id_from_sid,
index 4643b7db59d01b2987383889958d991e15d01151..7f8dce1f1a1d85c0086617f937877f2ab97855f4 100644 (file)
@@ -59,7 +59,45 @@ TDB_CONTEXT *idmap_tdb_handle( void )
        return NULL;
 }
 
-/* Allocate either a user or group id from the pool */
+/**********************************************************************
+ allocate a new RID; We don't care if is a user or group
+**********************************************************************/
+
+static NTSTATUS db_allocate_rid(uint32 *rid, int rid_type)
+{
+       uint32 lowrid, highrid;
+       uint32 tmp_rid;
+
+       /* can't handle group rids right now.  This is such a mess.... */
+
+       if ( rid_type == GROUP_RID_TYPE )
+               return NT_STATUS_UNSUCCESSFUL;
+       
+       /* cannot fail since idmap is only called winbindd */
+       
+       idmap_get_free_rid_range( &lowrid, &highrid );
+       
+       tmp_rid = lowrid;
+       
+       if ( !tdb_change_uint32_atomic(idmap_tdb, "RID_COUNTER", &tmp_rid, RID_MULTIPLIER) ) {
+               DEBUG(3,("db_allocate_rid: Failed to locate next rid record in idmap db\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+       
+       if ( tmp_rid > highrid ) {
+               DEBUG(0, ("db_allocate_rid: no RIDs available!\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+       
+       *rid = tmp_rid;
+
+       return NT_STATUS_OK;
+}
+
+/**********************************************************************
+ Allocate either a user or group id from the pool 
+**********************************************************************/
 static NTSTATUS db_allocate_id(unid_t *id, int id_type)
 {
        BOOL ret;
@@ -609,6 +647,7 @@ static void db_idmap_status(void)
 static struct idmap_methods db_methods = {
 
        db_idmap_init,
+       db_allocate_rid,
        db_allocate_id,
        db_get_sid_from_id,
        db_get_id_from_sid,
index 94de30a5ce5f8e7d6b4ac1a966ef3b39658a31ac..f767cc898c7619ec3097187b5bc2afb8097a5b1c 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
 
+/**********************************************************************
+**********************************************************************/
+
+BOOL idmap_get_free_ugid_range(uint32 *low, uint32 *high)
+{
+       uid_t u_low, u_high;
+       gid_t g_low, g_high;
+
+       if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
+               return False;
+       }
+       
+       *low  = (u_low < g_low)   ? u_low  : g_low;
+       *high = (u_high < g_high) ? u_high : g_high;
+       
+       return True;
+}
+
+/******************************************************************
+ Get the the non-algorithmic RID range if idmap range are defined
+******************************************************************/
+
+BOOL idmap_get_free_rid_range(uint32 *low, uint32 *high)
+{
+       uint32 id_low, id_high;
+
+       if (!lp_enable_rid_algorithm()) {
+               *low = BASE_RID;
+               *high = (uint32)-1;
+       }
+
+       if (!idmap_get_free_ugid_range(&id_low, &id_high)) {
+               return False;
+       }
+
+       *low = fallback_pdb_uid_to_user_rid(id_low);
+       if (fallback_pdb_user_rid_to_uid((uint32)-1) < id_high) {
+               *high = (uint32)-1;
+       } else {
+               *high = fallback_pdb_uid_to_user_rid(id_high);
+       }
+
+       return True;
+}
+
+/**********************************************************************
+ Get the free RID base if idmap is configured, otherwise return 0
+**********************************************************************/
+
+uint32 idmap_get_free_rid_base(void)
+{
+       uint32 low, high;
+       if (idmap_get_free_rid_range(&low, &high)) {
+               return low;
+       }
+       return 0;
+}
+
+/**********************************************************************
+**********************************************************************/
+
+BOOL idmap_check_ugid_is_in_free_range(uint32 id)
+{
+       uint32 low, high;
+
+       if (!idmap_get_free_ugid_range(&low, &high)) {
+               return False;
+       }
+       if (id < low || id > high) {
+               return False;
+       }
+       return True;
+}
+
+/**********************************************************************
+**********************************************************************/
+
+BOOL idmap_check_rid_is_in_free_range(uint32 rid)
+{
+       uint32 low, high;
+
+       if (!idmap_get_free_rid_range(&low, &high)) {
+               return False;
+       }
+       if (rid < algorithmic_rid_base()) {
+               return True;
+       }
+
+       if (rid < low || rid > high) {
+               return False;
+       }
+
+       return True;
+}
+
+/**********************************************************************
+ if it is a foreign SID or if the SID is in the free range, return true
+**********************************************************************/
+
+BOOL idmap_check_sid_is_in_free_range(const DOM_SID *sid)
+{
+       if (sid_compare_domain(get_global_sam_sid(), sid) == 0) {
+       
+               uint32 rid;
+
+               if (sid_peek_rid(sid, &rid)) {
+                       return idmap_check_rid_is_in_free_range(rid);
+               }
+
+               return False;
+       }
+
+       return True;
+}
 
 /*****************************************************************
  Returns SID pointer.
index 4b31c061f393c60be14fe9bb6f2516cfef533017..31535f794572f7b26c58d2020b03f5776741ca84 100644 (file)
@@ -444,7 +444,9 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
                }
                else {
                        DEBUG(8,("fetch_account_info: no add user/machine script.  Asking winbindd\n"));
-                       if ( !winbind_create_user( account ) )
+                       
+                       /* don't need a RID allocated since the user already has a SID */
+                       if ( !winbind_create_user( account, NULL ) )
                                DEBUG(4,("fetch_account_info: winbind_create_user() failed\n"));
                }
                
index b79972aa35eb7e97ec00113d4433ed1b92cb793d..96d0d3c057fad35fe5fe0e0d7be71992c462ad7e 100644 (file)
@@ -350,7 +350,7 @@ static int new_user (struct pdb_context *in, const char *username,
        NTSTATUS nt_status;
        char *password1, *password2, *staticpass;
        
-       if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pwent, username))) {
+       if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pwent, username, 0))) {
                DEBUG(0, ("could not create account to add new user %s\n", username));
                return -1;
        }