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.

20 files changed:
source/auth/auth_util.c
source/groupdb/mapping.c
source/include/idmap.h
source/lib/smbldap.c
source/nsswitch/wb_client.c
source/nsswitch/wbinfo.c
source/nsswitch/winbindd_acct.c
source/nsswitch/winbindd_nss.h
source/nsswitch/winbindd_user.c
source/passdb/passdb.c
source/passdb/pdb_ldap.c
source/passdb/pdb_smbpasswd.c
source/passdb/pdb_tdb.c
source/rpc_server/srv_samr_nt.c
source/sam/idmap.c
source/sam/idmap_ldap.c
source/sam/idmap_tdb.c
source/sam/idmap_util.c
source/utils/net_rpc_samsync.c
source/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;
        }