passdb/pdb_interface.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Password and authentication handling
00004    Copyright (C) Andrew Bartlett                        2002
00005    Copyright (C) Jelmer Vernooij                        2002
00006    Copyright (C) Simo Sorce                             2003
00007    Copyright (C) Volker Lendecke                        2006
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022 */
00023 
00024 #include "includes.h"
00025 
00026 #undef DBGC_CLASS
00027 #define DBGC_CLASS DBGC_PASSDB
00028 
00029 /* Cache of latest SAM lookup query */
00030 
00031 static struct samu *csamuser = NULL;
00032 
00033 static_decl_pdb;
00034 
00035 static struct pdb_init_function_entry *backends = NULL;
00036 
00037 static void lazy_initialize_passdb(void)
00038 {
00039         static BOOL initialized = False;
00040         if(initialized) {
00041                 return;
00042         }
00043         static_init_pdb;
00044         initialized = True;
00045 }
00046 
00047 static BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
00048                                   const char **name,
00049                                   enum lsa_SidType *psid_name_use,
00050                                   union unid_t *unix_id);
00051 
00052 NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init) 
00053 {
00054         struct pdb_init_function_entry *entry = backends;
00055 
00056         if(version != PASSDB_INTERFACE_VERSION) {
00057                 DEBUG(0,("Can't register passdb backend!\n"
00058                          "You tried to register a passdb module with PASSDB_INTERFACE_VERSION %d, "
00059                          "while this version of samba uses version %d\n", 
00060                          version,PASSDB_INTERFACE_VERSION));
00061                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
00062         }
00063 
00064         if (!name || !init) {
00065                 return NT_STATUS_INVALID_PARAMETER;
00066         }
00067 
00068         DEBUG(5,("Attempting to register passdb backend %s\n", name));
00069 
00070         /* Check for duplicates */
00071         if (pdb_find_backend_entry(name)) {
00072                 DEBUG(0,("There already is a passdb backend registered with the name %s!\n", name));
00073                 return NT_STATUS_OBJECT_NAME_COLLISION;
00074         }
00075 
00076         entry = SMB_XMALLOC_P(struct pdb_init_function_entry);
00077         entry->name = smb_xstrdup(name);
00078         entry->init = init;
00079 
00080         DLIST_ADD(backends, entry);
00081         DEBUG(5,("Successfully added passdb backend '%s'\n", name));
00082         return NT_STATUS_OK;
00083 }
00084 
00085 struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
00086 {
00087         struct pdb_init_function_entry *entry = backends;
00088 
00089         while(entry) {
00090                 if (strcmp(entry->name, name)==0) return entry;
00091                 entry = entry->next;
00092         }
00093 
00094         return NULL;
00095 }
00096 
00097 /******************************************************************
00098   Make a pdb_methods from scratch
00099  *******************************************************************/
00100 
00101 NTSTATUS make_pdb_method_name(struct pdb_methods **methods, const char *selected)
00102 {
00103         char *module_name = smb_xstrdup(selected);
00104         char *module_location = NULL, *p;
00105         struct pdb_init_function_entry *entry;
00106         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
00107 
00108         lazy_initialize_passdb();
00109 
00110         p = strchr(module_name, ':');
00111 
00112         if (p) {
00113                 *p = 0;
00114                 module_location = p+1;
00115                 trim_char(module_location, ' ', ' ');
00116         }
00117 
00118         trim_char(module_name, ' ', ' ');
00119 
00120 
00121         DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
00122 
00123         entry = pdb_find_backend_entry(module_name);
00124         
00125         /* Try to find a module that contains this module */
00126         if (!entry) { 
00127                 DEBUG(2,("No builtin backend found, trying to load plugin\n"));
00128                 if(NT_STATUS_IS_OK(smb_probe_module("pdb", module_name)) && !(entry = pdb_find_backend_entry(module_name))) {
00129                         DEBUG(0,("Plugin is available, but doesn't register passdb backend %s\n", module_name));
00130                         SAFE_FREE(module_name);
00131                         return NT_STATUS_UNSUCCESSFUL;
00132                 }
00133         }
00134         
00135         /* No such backend found */
00136         if(!entry) { 
00137                 DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name));
00138                 SAFE_FREE(module_name);
00139                 return NT_STATUS_INVALID_PARAMETER;
00140         }
00141 
00142         DEBUG(5,("Found pdb backend %s\n", module_name));
00143 
00144         if ( !NT_STATUS_IS_OK( nt_status = entry->init(methods, module_location) ) ) {
00145                 DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", 
00146                         selected, nt_errstr(nt_status)));
00147                 SAFE_FREE(module_name);
00148                 return nt_status;
00149         }
00150 
00151         SAFE_FREE(module_name);
00152 
00153         DEBUG(5,("pdb backend %s has a valid init\n", selected));
00154 
00155         return nt_status;
00156 }
00157 
00158 /******************************************************************
00159  Return an already initialised pdn_methods structure
00160 *******************************************************************/
00161 
00162 static struct pdb_methods *pdb_get_methods_reload( BOOL reload ) 
00163 {
00164         static struct pdb_methods *pdb = NULL;
00165 
00166         if ( pdb && reload ) {
00167                 pdb->free_private_data( &(pdb->private_data) );
00168                 if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) {
00169                         pstring msg;
00170                         slprintf(msg, sizeof(msg)-1, "pdb_get_methods_reload: failed to get pdb methods for backend %s\n",
00171                                 lp_passdb_backend() );
00172                         smb_panic(msg);
00173                 }
00174         }
00175 
00176         if ( !pdb ) {
00177                 if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) {
00178                         pstring msg;
00179                         slprintf(msg, sizeof(msg)-1, "pdb_get_methods_reload: failed to get pdb methods for backend %s\n",
00180                                 lp_passdb_backend() );
00181                         smb_panic(msg);
00182                 }
00183         }
00184 
00185         return pdb;
00186 }
00187 
00188 static struct pdb_methods *pdb_get_methods(void)
00189 {
00190         return pdb_get_methods_reload(False);
00191 }
00192 
00193 /******************************************************************
00194  Backward compatibility functions for the original passdb interface
00195 *******************************************************************/
00196 
00197 BOOL pdb_setsampwent(BOOL update, uint16 acb_mask) 
00198 {
00199         struct pdb_methods *pdb = pdb_get_methods();
00200         return NT_STATUS_IS_OK(pdb->setsampwent(pdb, update, acb_mask));
00201 }
00202 
00203 void pdb_endsampwent(void) 
00204 {
00205         struct pdb_methods *pdb = pdb_get_methods();
00206         pdb->endsampwent(pdb);
00207 }
00208 
00209 BOOL pdb_getsampwent(struct samu *user) 
00210 {
00211         struct pdb_methods *pdb = pdb_get_methods();
00212 
00213         if ( !NT_STATUS_IS_OK(pdb->getsampwent(pdb, user) ) ) {
00214                 return False;
00215         }
00216 
00217         return True;
00218 }
00219 
00220 BOOL pdb_getsampwnam(struct samu *sam_acct, const char *username) 
00221 {
00222         struct pdb_methods *pdb = pdb_get_methods();
00223 
00224         if (!NT_STATUS_IS_OK(pdb->getsampwnam(pdb, sam_acct, username))) {
00225                 return False;
00226         }
00227 
00228         if ( csamuser ) {
00229                 TALLOC_FREE(csamuser);
00230         }
00231 
00232         csamuser = samu_new( NULL );
00233         if (!csamuser) {
00234                 return False;
00235         }
00236 
00237         if (!pdb_copy_sam_account(csamuser, sam_acct)) {
00238                 TALLOC_FREE(csamuser);
00239                 return False;
00240         }
00241 
00242         return True;
00243 }
00244 
00245 /**********************************************************************
00246 **********************************************************************/
00247 
00248 BOOL guest_user_info( struct samu *user )
00249 {
00250         struct passwd *pwd;
00251         NTSTATUS result;
00252         const char *guestname = lp_guestaccount();
00253         
00254         if ( !(pwd = getpwnam_alloc( NULL, guestname ) ) ) {
00255                 DEBUG(0,("guest_user_info: Unable to locate guest account [%s]!\n", 
00256                         guestname));
00257                 return False;
00258         }
00259         
00260         result = samu_set_unix(user, pwd );
00261 
00262         TALLOC_FREE( pwd );
00263 
00264         return NT_STATUS_IS_OK( result );
00265 }
00266 
00267 /**********************************************************************
00268 **********************************************************************/
00269 
00270 BOOL pdb_getsampwsid(struct samu *sam_acct, const DOM_SID *sid) 
00271 {
00272         struct pdb_methods *pdb = pdb_get_methods();
00273         uint32 rid;
00274 
00275         /* hard code the Guest RID of 501 */
00276 
00277         if ( !sid_peek_check_rid( get_global_sam_sid(), sid, &rid ) )
00278                 return False;
00279 
00280         if ( rid == DOMAIN_USER_RID_GUEST ) {
00281                 DEBUG(6,("pdb_getsampwsid: Building guest account\n"));
00282                 return guest_user_info( sam_acct );
00283         }
00284         
00285         /* check the cache first */
00286         
00287         if ( csamuser && sid_equal(sid, pdb_get_user_sid(csamuser) ) )
00288                 return pdb_copy_sam_account(sam_acct, csamuser);
00289 
00290         return NT_STATUS_IS_OK(pdb->getsampwsid(pdb, sam_acct, sid));
00291 }
00292 
00293 static NTSTATUS pdb_default_create_user(struct pdb_methods *methods,
00294                                         TALLOC_CTX *tmp_ctx, const char *name,
00295                                         uint32 acb_info, uint32 *rid)
00296 {
00297         struct samu *sam_pass;
00298         NTSTATUS status;
00299         struct passwd *pwd;
00300 
00301         if ((sam_pass = samu_new(tmp_ctx)) == NULL) {
00302                 return NT_STATUS_NO_MEMORY;
00303         }
00304 
00305         if ( !(pwd = Get_Pwnam_alloc(tmp_ctx, name)) ) {
00306                 pstring add_script;
00307                 int add_ret;
00308                 fstring name2;
00309 
00310                 if ((acb_info & ACB_NORMAL) && name[strlen(name)-1] != '$') {
00311                         pstrcpy(add_script, lp_adduser_script());
00312                 } else {
00313                         pstrcpy(add_script, lp_addmachine_script());
00314                 }
00315 
00316                 if (add_script[0] == '\0') {
00317                         DEBUG(3, ("Could not find user %s and no add script "
00318                                   "defined\n", name));
00319                         return NT_STATUS_NO_SUCH_USER;
00320                 }
00321 
00322                 /* lowercase the username before creating the Unix account for 
00323                    compatibility with previous Samba releases */
00324                 fstrcpy( name2, name );
00325                 strlower_m( name2 );
00326                 all_string_sub(add_script, "%u", name2, sizeof(add_script));
00327                 add_ret = smbrun(add_script,NULL);
00328                 DEBUG(add_ret ? 0 : 3, ("_samr_create_user: Running the command `%s' gave %d\n",
00329                                         add_script, add_ret));
00330                 if (add_ret == 0) {
00331                         smb_nscd_flush_user_cache();
00332                 }
00333 
00334 #ifdef ENABLE_BUILD_FARM_HACKS
00335                 if (add_ret != 0) {
00336                         DEBUG(1, ("Creating a faked user %s for build farm "
00337                                   "purposes\n", name));
00338                         faked_create_user(name);
00339                 }
00340 #endif
00341 
00342                 flush_pwnam_cache();
00343 
00344                 pwd = Get_Pwnam_alloc(tmp_ctx, name);
00345         }
00346 
00347         /* we have a valid SID coming out of this call */
00348 
00349         status = samu_alloc_rid_unix( sam_pass, pwd );
00350 
00351         TALLOC_FREE( pwd );
00352 
00353         if (!NT_STATUS_IS_OK(status)) {
00354                 DEBUG(3, ("pdb_default_create_user: failed to create a new user structure: %s\n", nt_errstr(status)));
00355                 return status;
00356         }
00357 
00358         if (!sid_peek_check_rid(get_global_sam_sid(),
00359                                 pdb_get_user_sid(sam_pass), rid)) {
00360                 DEBUG(0, ("Could not get RID of fresh user\n"));
00361                 return NT_STATUS_INTERNAL_ERROR;
00362         }
00363 
00364         /* Use the username case specified in the original request */
00365 
00366         pdb_set_username( sam_pass, name, PDB_SET );
00367 
00368         /* Disable the account on creation, it does not have a reasonable password yet. */
00369 
00370         acb_info |= ACB_DISABLED;
00371 
00372         pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
00373 
00374         status = pdb_add_sam_account(sam_pass);
00375 
00376         TALLOC_FREE(sam_pass);
00377 
00378         return status;
00379 }
00380 
00381 NTSTATUS pdb_create_user(TALLOC_CTX *mem_ctx, const char *name, uint32 flags,
00382                          uint32 *rid)
00383 {
00384         struct pdb_methods *pdb = pdb_get_methods();
00385         return pdb->create_user(pdb, mem_ctx, name, flags, rid);
00386 }
00387 
00388 /****************************************************************************
00389  Delete a UNIX user on demand.
00390 ****************************************************************************/
00391 
00392 static int smb_delete_user(const char *unix_user)
00393 {
00394         pstring del_script;
00395         int ret;
00396 
00397         /* safety check */
00398 
00399         if ( strequal( unix_user, "root" ) ) {
00400                 DEBUG(0,("smb_delete_user: Refusing to delete local system root account!\n"));
00401                 return -1;
00402         }
00403 
00404         pstrcpy(del_script, lp_deluser_script());
00405         if (! *del_script)
00406                 return -1;
00407         all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
00408         ret = smbrun(del_script,NULL);
00409         flush_pwnam_cache();
00410         if (ret == 0) {
00411                 smb_nscd_flush_user_cache();
00412         }
00413         DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
00414 
00415         return ret;
00416 }
00417 
00418 static NTSTATUS pdb_default_delete_user(struct pdb_methods *methods,
00419                                         TALLOC_CTX *mem_ctx,
00420                                         struct samu *sam_acct)
00421 {
00422         NTSTATUS status;
00423         fstring username;
00424 
00425         status = pdb_delete_sam_account(sam_acct);
00426         if (!NT_STATUS_IS_OK(status)) {
00427                 return status;
00428         }
00429 
00430         /*
00431          * Now delete the unix side ....
00432          * note: we don't check if the delete really happened as the script is
00433          * not necessary present and maybe the sysadmin doesn't want to delete
00434          * the unix side
00435          */
00436 
00437         /* always lower case the username before handing it off to 
00438            external scripts */
00439 
00440         fstrcpy( username, pdb_get_username(sam_acct) );
00441         strlower_m( username );
00442 
00443         smb_delete_user( username );
00444         
00445         return status;
00446 }
00447 
00448 NTSTATUS pdb_delete_user(TALLOC_CTX *mem_ctx, struct samu *sam_acct)
00449 {
00450         struct pdb_methods *pdb = pdb_get_methods();
00451         uid_t uid = -1;
00452 
00453         /* sanity check to make sure we don't delete root */
00454 
00455         if ( !sid_to_uid( pdb_get_user_sid(sam_acct), &uid ) ) {
00456                 return NT_STATUS_NO_SUCH_USER;
00457         }
00458 
00459         if ( uid == 0 ) {
00460                 return NT_STATUS_ACCESS_DENIED;
00461         }
00462 
00463         return pdb->delete_user(pdb, mem_ctx, sam_acct);
00464 }
00465 
00466 NTSTATUS pdb_add_sam_account(struct samu *sam_acct) 
00467 {
00468         struct pdb_methods *pdb = pdb_get_methods();
00469         return pdb->add_sam_account(pdb, sam_acct);
00470 }
00471 
00472 NTSTATUS pdb_update_sam_account(struct samu *sam_acct) 
00473 {
00474         struct pdb_methods *pdb = pdb_get_methods();
00475 
00476         if (csamuser != NULL) {
00477                 TALLOC_FREE(csamuser);
00478                 csamuser = NULL;
00479         }
00480 
00481         return pdb->update_sam_account(pdb, sam_acct);
00482 }
00483 
00484 NTSTATUS pdb_delete_sam_account(struct samu *sam_acct) 
00485 {
00486         struct pdb_methods *pdb = pdb_get_methods();
00487 
00488         if (csamuser != NULL) {
00489                 TALLOC_FREE(csamuser);
00490                 csamuser = NULL;
00491         }
00492 
00493         return pdb->delete_sam_account(pdb, sam_acct);
00494 }
00495 
00496 NTSTATUS pdb_rename_sam_account(struct samu *oldname, const char *newname)
00497 {
00498         struct pdb_methods *pdb = pdb_get_methods();
00499         uid_t uid;
00500         NTSTATUS status;
00501 
00502         if (csamuser != NULL) {
00503                 TALLOC_FREE(csamuser);
00504                 csamuser = NULL;
00505         }
00506 
00507         /* sanity check to make sure we don't rename root */
00508 
00509         if ( !sid_to_uid( pdb_get_user_sid(oldname), &uid ) ) {
00510                 return NT_STATUS_NO_SUCH_USER;
00511         }
00512 
00513         if ( uid == 0 ) {
00514                 return NT_STATUS_ACCESS_DENIED;
00515         }
00516 
00517         status = pdb->rename_sam_account(pdb, oldname, newname);
00518 
00519         /* always flush the cache here just to be safe */
00520         flush_pwnam_cache();
00521 
00522         return status;
00523 }
00524 
00525 NTSTATUS pdb_update_login_attempts(struct samu *sam_acct, BOOL success)
00526 {
00527         struct pdb_methods *pdb = pdb_get_methods();
00528         return pdb->update_login_attempts(pdb, sam_acct, success);
00529 }
00530 
00531 BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid)
00532 {
00533         struct pdb_methods *pdb = pdb_get_methods();
00534         return NT_STATUS_IS_OK(pdb->getgrsid(pdb, map, sid));
00535 }
00536 
00537 BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid)
00538 {
00539         struct pdb_methods *pdb = pdb_get_methods();
00540         return NT_STATUS_IS_OK(pdb->getgrgid(pdb, map, gid));
00541 }
00542 
00543 BOOL pdb_getgrnam(GROUP_MAP *map, const char *name)
00544 {
00545         struct pdb_methods *pdb = pdb_get_methods();
00546         return NT_STATUS_IS_OK(pdb->getgrnam(pdb, map, name));
00547 }
00548 
00549 static NTSTATUS pdb_default_create_dom_group(struct pdb_methods *methods,
00550                                              TALLOC_CTX *mem_ctx,
00551                                              const char *name,
00552                                              uint32 *rid)
00553 {
00554         DOM_SID group_sid;
00555         struct group *grp;
00556 
00557         grp = getgrnam(name);
00558 
00559         if (grp == NULL) {
00560                 gid_t gid;
00561 
00562                 if (smb_create_group(name, &gid) != 0) {
00563                         return NT_STATUS_ACCESS_DENIED;
00564                 }
00565 
00566                 grp = getgrgid(gid);
00567         }
00568 
00569         if (grp == NULL) {
00570                 return NT_STATUS_ACCESS_DENIED;
00571         }
00572 
00573         if (pdb_rid_algorithm()) {
00574                 *rid = algorithmic_pdb_gid_to_group_rid( grp->gr_gid );
00575         } else {
00576                 if (!pdb_new_rid(rid)) {
00577                         return NT_STATUS_ACCESS_DENIED;
00578                 }
00579         }
00580 
00581         sid_compose(&group_sid, get_global_sam_sid(), *rid);
00582                 
00583         return add_initial_entry(grp->gr_gid, sid_string_static(&group_sid),
00584                                  SID_NAME_DOM_GRP, name, NULL);
00585 }
00586 
00587 NTSTATUS pdb_create_dom_group(TALLOC_CTX *mem_ctx, const char *name,
00588                               uint32 *rid)
00589 {
00590         struct pdb_methods *pdb = pdb_get_methods();
00591         return pdb->create_dom_group(pdb, mem_ctx, name, rid);
00592 }
00593 
00594 static NTSTATUS pdb_default_delete_dom_group(struct pdb_methods *methods,
00595                                              TALLOC_CTX *mem_ctx,
00596                                              uint32 rid)
00597 {
00598         DOM_SID group_sid;
00599         GROUP_MAP map;
00600         NTSTATUS status;
00601         struct group *grp;
00602         const char *grp_name;
00603 
00604         sid_compose(&group_sid, get_global_sam_sid(), rid);
00605 
00606         if (!get_domain_group_from_sid(group_sid, &map)) {
00607                 DEBUG(10, ("Could not find group for rid %d\n", rid));
00608                 return NT_STATUS_NO_SUCH_GROUP;
00609         }
00610 
00611         /* We need the group name for the smb_delete_group later on */
00612 
00613         if (map.gid == (gid_t)-1) {
00614                 return NT_STATUS_NO_SUCH_GROUP;
00615         }
00616 
00617         grp = getgrgid(map.gid);
00618         if (grp == NULL) {
00619                 return NT_STATUS_NO_SUCH_GROUP;
00620         }
00621 
00622         /* Copy the name, no idea what pdb_delete_group_mapping_entry does.. */
00623 
00624         grp_name = talloc_strdup(mem_ctx, grp->gr_name);
00625         if (grp_name == NULL) {
00626                 return NT_STATUS_NO_MEMORY;
00627         }
00628 
00629         status = pdb_delete_group_mapping_entry(group_sid);
00630 
00631         if (!NT_STATUS_IS_OK(status)) {
00632                 return status;
00633         }
00634 
00635         /* Don't check the result of smb_delete_group */
00636         
00637         smb_delete_group(grp_name);
00638 
00639         return NT_STATUS_OK;
00640 }
00641 
00642 NTSTATUS pdb_delete_dom_group(TALLOC_CTX *mem_ctx, uint32 rid)
00643 {
00644         struct pdb_methods *pdb = pdb_get_methods();
00645         return pdb->delete_dom_group(pdb, mem_ctx, rid);
00646 }
00647 
00648 NTSTATUS pdb_add_group_mapping_entry(GROUP_MAP *map)
00649 {
00650         struct pdb_methods *pdb = pdb_get_methods();
00651         return pdb->add_group_mapping_entry(pdb, map);
00652 }
00653 
00654 NTSTATUS pdb_update_group_mapping_entry(GROUP_MAP *map)
00655 {
00656         struct pdb_methods *pdb = pdb_get_methods();
00657         return pdb->update_group_mapping_entry(pdb, map);
00658 }
00659 
00660 NTSTATUS pdb_delete_group_mapping_entry(DOM_SID sid)
00661 {
00662         struct pdb_methods *pdb = pdb_get_methods();
00663         return pdb->delete_group_mapping_entry(pdb, sid);
00664 }
00665 
00666 BOOL pdb_enum_group_mapping(const DOM_SID *sid, enum lsa_SidType sid_name_use, GROUP_MAP **pp_rmap,
00667                             size_t *p_num_entries, BOOL unix_only)
00668 {
00669         struct pdb_methods *pdb = pdb_get_methods();
00670         return NT_STATUS_IS_OK(pdb-> enum_group_mapping(pdb, sid, sid_name_use,
00671                 pp_rmap, p_num_entries, unix_only));
00672 }
00673 
00674 NTSTATUS pdb_enum_group_members(TALLOC_CTX *mem_ctx,
00675                                 const DOM_SID *sid,
00676                                 uint32 **pp_member_rids,
00677                                 size_t *p_num_members)
00678 {
00679         struct pdb_methods *pdb = pdb_get_methods();
00680         NTSTATUS result;
00681 
00682         result = pdb->enum_group_members(pdb, mem_ctx, 
00683                         sid, pp_member_rids, p_num_members);
00684                 
00685         /* special check for rid 513 */
00686                 
00687         if ( !NT_STATUS_IS_OK( result ) ) {
00688                 uint32 rid;
00689                 
00690                 sid_peek_rid( sid, &rid );
00691                 
00692                 if ( rid == DOMAIN_GROUP_RID_USERS ) {
00693                         *p_num_members = 0;
00694                         *pp_member_rids = NULL;
00695                         
00696                         return NT_STATUS_OK;
00697                 }
00698         }
00699         
00700         return result;
00701 }
00702 
00703 NTSTATUS pdb_enum_group_memberships(TALLOC_CTX *mem_ctx, struct samu *user,
00704                                     DOM_SID **pp_sids, gid_t **pp_gids,
00705                                     size_t *p_num_groups)
00706 {
00707         struct pdb_methods *pdb = pdb_get_methods();
00708         return pdb->enum_group_memberships(
00709                 pdb, mem_ctx, user,
00710                 pp_sids, pp_gids, p_num_groups);
00711 }
00712 
00713 static NTSTATUS pdb_default_set_unix_primary_group(struct pdb_methods *methods,
00714                                                    TALLOC_CTX *mem_ctx,
00715                                                    struct samu *sampass)
00716 {
00717         struct group *grp;
00718         gid_t gid;
00719 
00720         if (!sid_to_gid(pdb_get_group_sid(sampass), &gid) ||
00721             (grp = getgrgid(gid)) == NULL) {
00722                 return NT_STATUS_INVALID_PRIMARY_GROUP;
00723         }
00724 
00725         if (smb_set_primary_group(grp->gr_name,
00726                                   pdb_get_username(sampass)) != 0) {
00727                 return NT_STATUS_ACCESS_DENIED;
00728         }
00729 
00730         return NT_STATUS_OK;
00731 }
00732 
00733 NTSTATUS pdb_set_unix_primary_group(TALLOC_CTX *mem_ctx, struct samu *user)
00734 {
00735         struct pdb_methods *pdb = pdb_get_methods();
00736         return pdb->set_unix_primary_group(pdb, mem_ctx, user);
00737 }
00738 
00739 /*
00740  * Helper function to see whether a user is in a group. We can't use
00741  * user_in_group_sid here because this creates dependencies only smbd can
00742  * fulfil.
00743  */
00744 
00745 static BOOL pdb_user_in_group(TALLOC_CTX *mem_ctx, struct samu *account,
00746                               const DOM_SID *group_sid)
00747 {
00748         DOM_SID *sids;
00749         gid_t *gids;
00750         size_t i, num_groups;
00751 
00752         if (!NT_STATUS_IS_OK(pdb_enum_group_memberships(mem_ctx, account,
00753                                                         &sids, &gids,
00754                                                         &num_groups))) {
00755                 return False;
00756         }
00757 
00758         for (i=0; i<num_groups; i++) {
00759                 if (sid_equal(group_sid, &sids[i])) {
00760                         return True;
00761                 }
00762         }
00763         return False;
00764 }
00765 
00766 static NTSTATUS pdb_default_add_groupmem(struct pdb_methods *methods,
00767                                          TALLOC_CTX *mem_ctx,
00768                                          uint32 group_rid,
00769                                          uint32 member_rid)
00770 {
00771         DOM_SID group_sid, member_sid;
00772         struct samu *account = NULL;
00773         GROUP_MAP map;
00774         struct group *grp;
00775         struct passwd *pwd;
00776         const char *group_name;
00777         uid_t uid;
00778 
00779         sid_compose(&group_sid, get_global_sam_sid(), group_rid);
00780         sid_compose(&member_sid, get_global_sam_sid(), member_rid);
00781 
00782         if (!get_domain_group_from_sid(group_sid, &map) ||
00783             (map.gid == (gid_t)-1) ||
00784             ((grp = getgrgid(map.gid)) == NULL)) {
00785                 return NT_STATUS_NO_SUCH_GROUP;
00786         }
00787 
00788         group_name = talloc_strdup(mem_ctx, grp->gr_name);
00789         if (group_name == NULL) {
00790                 return NT_STATUS_NO_MEMORY;
00791         }
00792 
00793         if ( !(account = samu_new( NULL )) ) {
00794                 return NT_STATUS_NO_MEMORY;
00795         }
00796 
00797         if (!pdb_getsampwsid(account, &member_sid) ||
00798             !sid_to_uid(&member_sid, &uid) ||
00799             ((pwd = getpwuid_alloc(mem_ctx, uid)) == NULL)) {
00800                 return NT_STATUS_NO_SUCH_USER;
00801         }
00802 
00803         if (pdb_user_in_group(mem_ctx, account, &group_sid)) {
00804                 return NT_STATUS_MEMBER_IN_GROUP;
00805         }
00806 
00807         /* 
00808          * ok, the group exist, the user exist, the user is not in the group,
00809          * we can (finally) add it to the group !
00810          */
00811 
00812         smb_add_user_group(group_name, pwd->pw_name);
00813 
00814         if (!pdb_user_in_group(mem_ctx, account, &group_sid)) {
00815                 return NT_STATUS_ACCESS_DENIED;
00816         }
00817 
00818         return NT_STATUS_OK;
00819 }
00820 
00821 NTSTATUS pdb_add_groupmem(TALLOC_CTX *mem_ctx, uint32 group_rid,
00822                           uint32 member_rid)
00823 {
00824         struct pdb_methods *pdb = pdb_get_methods();
00825         return pdb->add_groupmem(pdb, mem_ctx, group_rid, member_rid);
00826 }
00827 
00828 static NTSTATUS pdb_default_del_groupmem(struct pdb_methods *methods,
00829                                          TALLOC_CTX *mem_ctx,
00830                                          uint32 group_rid,
00831                                          uint32 member_rid)
00832 {
00833         DOM_SID group_sid, member_sid;
00834         struct samu *account = NULL;
00835         GROUP_MAP map;
00836         struct group *grp;
00837         struct passwd *pwd;
00838         const char *group_name;
00839         uid_t uid;
00840 
00841         sid_compose(&group_sid, get_global_sam_sid(), group_rid);
00842         sid_compose(&member_sid, get_global_sam_sid(), member_rid);
00843 
00844         if (!get_domain_group_from_sid(group_sid, &map) ||
00845             (map.gid == (gid_t)-1) ||
00846             ((grp = getgrgid(map.gid)) == NULL)) {
00847                 return NT_STATUS_NO_SUCH_GROUP;
00848         }
00849 
00850         group_name = talloc_strdup(mem_ctx, grp->gr_name);
00851         if (group_name == NULL) {
00852                 return NT_STATUS_NO_MEMORY;
00853         }
00854 
00855         if ( !(account = samu_new( NULL )) ) {
00856                 return NT_STATUS_NO_MEMORY;
00857         }
00858 
00859         if (!pdb_getsampwsid(account, &member_sid) ||
00860             !sid_to_uid(&member_sid, &uid) ||
00861             ((pwd = getpwuid_alloc(mem_ctx, uid)) == NULL)) {
00862                 return NT_STATUS_NO_SUCH_USER;
00863         }
00864 
00865         if (!pdb_user_in_group(mem_ctx, account, &group_sid)) {
00866                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
00867         }
00868 
00869         /* 
00870          * ok, the group exist, the user exist, the user is in the group,
00871          * we can (finally) delete it from the group!
00872          */
00873 
00874         smb_delete_user_group(group_name, pwd->pw_name);
00875 
00876         if (pdb_user_in_group(mem_ctx, account, &group_sid)) {
00877                 return NT_STATUS_ACCESS_DENIED;
00878         }
00879 
00880         return NT_STATUS_OK;
00881 }
00882 
00883 NTSTATUS pdb_del_groupmem(TALLOC_CTX *mem_ctx, uint32 group_rid,
00884                           uint32 member_rid)
00885 {
00886         struct pdb_methods *pdb = pdb_get_methods();
00887         return pdb->del_groupmem(pdb, mem_ctx, group_rid, member_rid);
00888 }
00889 
00890 BOOL pdb_find_alias(const char *name, DOM_SID *sid)
00891 {
00892         struct pdb_methods *pdb = pdb_get_methods();
00893         return NT_STATUS_IS_OK(pdb->find_alias(pdb, name, sid));
00894 }
00895 
00896 NTSTATUS pdb_create_alias(const char *name, uint32 *rid)
00897 {
00898         struct pdb_methods *pdb = pdb_get_methods();
00899         return pdb->create_alias(pdb, name, rid);
00900 }
00901 
00902 BOOL pdb_delete_alias(const DOM_SID *sid)
00903 {
00904         struct pdb_methods *pdb = pdb_get_methods();
00905         return NT_STATUS_IS_OK(pdb->delete_alias(pdb, sid));
00906                                                             
00907 }
00908 
00909 BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
00910 {
00911         struct pdb_methods *pdb = pdb_get_methods();
00912         return NT_STATUS_IS_OK(pdb->get_aliasinfo(pdb, sid, info));
00913 }
00914 
00915 BOOL pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info)
00916 {
00917         struct pdb_methods *pdb = pdb_get_methods();
00918         return NT_STATUS_IS_OK(pdb->set_aliasinfo(pdb, sid, info));
00919 }
00920 
00921 NTSTATUS pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
00922 {
00923         struct pdb_methods *pdb = pdb_get_methods();
00924         return pdb->add_aliasmem(pdb, alias, member);
00925 }
00926 
00927 NTSTATUS pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
00928 {
00929         struct pdb_methods *pdb = pdb_get_methods();
00930         return pdb->del_aliasmem(pdb, alias, member);
00931 }
00932 
00933 NTSTATUS pdb_enum_aliasmem(const DOM_SID *alias,
00934                            DOM_SID **pp_members, size_t *p_num_members)
00935 {
00936         struct pdb_methods *pdb = pdb_get_methods();
00937         return pdb->enum_aliasmem(pdb, alias, pp_members, p_num_members);
00938 }
00939 
00940 NTSTATUS pdb_enum_alias_memberships(TALLOC_CTX *mem_ctx,
00941                                     const DOM_SID *domain_sid,
00942                                     const DOM_SID *members, size_t num_members,
00943                                     uint32 **pp_alias_rids,
00944                                     size_t *p_num_alias_rids)
00945 {
00946         struct pdb_methods *pdb = pdb_get_methods();
00947         return pdb->enum_alias_memberships(pdb, mem_ctx,
00948                                                        domain_sid,
00949                                                        members, num_members,
00950                                                        pp_alias_rids,
00951                                                        p_num_alias_rids);
00952 }
00953 
00954 NTSTATUS pdb_lookup_rids(const DOM_SID *domain_sid,
00955                          int num_rids,
00956                          uint32 *rids,
00957                          const char **names,
00958                          enum lsa_SidType *attrs)
00959 {
00960         struct pdb_methods *pdb = pdb_get_methods();
00961         return pdb->lookup_rids(pdb, domain_sid, num_rids, rids, names, attrs);
00962 }
00963 
00964 /* 
00965  * NOTE: pdb_lookup_names is currently (2007-01-12) not used anywhere 
00966  *       in the samba code.
00967  *       Unlike _lsa_lookup_sids and _samr_lookup_rids, which eventually 
00968  *       also ask pdb_lookup_rids, thus looking up a bunch of rids at a time, 
00969  *       the pdb_ calls _lsa_lookup_names and _samr_lookup_names come
00970  *       down to are pdb_getsampwnam and pdb_getgrnam instead of
00971  *       pdb_lookup_names.
00972  *       But in principle, it the call belongs to the API and might get
00973  *       used in this context some day. 
00974  */
00975 #if 0
00976 NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
00977                           int num_names,
00978                           const char **names,
00979                           uint32 *rids,
00980                           enum lsa_SidType *attrs)
00981 {
00982         struct pdb_methods *pdb = pdb_get_methods();
00983         return pdb->lookup_names(pdb, domain_sid, num_names, names, rids, attrs);
00984 }
00985 #endif
00986 
00987 BOOL pdb_get_account_policy(int policy_index, uint32 *value)
00988 {
00989         struct pdb_methods *pdb = pdb_get_methods();
00990         NTSTATUS status;
00991         
00992         become_root();
00993         status = pdb->get_account_policy(pdb, policy_index, value);
00994         unbecome_root();
00995         
00996         return NT_STATUS_IS_OK(status); 
00997 }
00998 
00999 BOOL pdb_set_account_policy(int policy_index, uint32 value)
01000 {
01001         struct pdb_methods *pdb = pdb_get_methods();
01002         NTSTATUS status;
01003 
01004         become_root();
01005         status = pdb->set_account_policy(pdb, policy_index, value);
01006         unbecome_root();
01007 
01008         return NT_STATUS_IS_OK(status);
01009 }
01010 
01011 BOOL pdb_get_seq_num(time_t *seq_num)
01012 {
01013         struct pdb_methods *pdb = pdb_get_methods();
01014         return NT_STATUS_IS_OK(pdb->get_seq_num(pdb, seq_num));
01015 }
01016 
01017 BOOL pdb_uid_to_rid(uid_t uid, uint32 *rid)
01018 {
01019         struct pdb_methods *pdb = pdb_get_methods();
01020         return pdb->uid_to_rid(pdb, uid, rid);
01021 }
01022 
01023 BOOL pdb_uid_to_sid(uid_t uid, DOM_SID *sid)
01024 {
01025         struct pdb_methods *pdb = pdb_get_methods();
01026         return pdb->uid_to_sid(pdb, uid, sid);
01027 }
01028 
01029 BOOL pdb_gid_to_sid(gid_t gid, DOM_SID *sid)
01030 {
01031         struct pdb_methods *pdb = pdb_get_methods();
01032         return pdb->gid_to_sid(pdb, gid, sid);
01033 }
01034 
01035 BOOL pdb_sid_to_id(const DOM_SID *sid, union unid_t *id,
01036                    enum lsa_SidType *type)
01037 {
01038         struct pdb_methods *pdb = pdb_get_methods();
01039         return pdb->sid_to_id(pdb, sid, id, type);
01040 }
01041 
01042 BOOL pdb_rid_algorithm(void)
01043 {
01044         struct pdb_methods *pdb = pdb_get_methods();
01045         return pdb->rid_algorithm(pdb);
01046 }
01047 
01048 /********************************************************************
01049  Allocate a new RID from the passdb backend.  Verify that it is free
01050  by calling lookup_global_sam_rid() to verify that the RID is not
01051  in use.  This handles servers that have existing users or groups
01052  with add RIDs (assigned from previous algorithmic mappings)
01053 ********************************************************************/
01054 
01055 BOOL pdb_new_rid(uint32 *rid)
01056 {
01057         struct pdb_methods *pdb = pdb_get_methods();
01058         const char *name = NULL;
01059         enum lsa_SidType type;
01060         uint32 allocated_rid = 0;
01061         int i;
01062         TALLOC_CTX *ctx;
01063 
01064         if (pdb_rid_algorithm()) {
01065                 DEBUG(0, ("Trying to allocate a RID when algorithmic RIDs "
01066                           "are active\n"));
01067                 return False;
01068         }
01069 
01070         if (algorithmic_rid_base() != BASE_RID) {
01071                 DEBUG(0, ("'algorithmic rid base' is set but a passdb backend "
01072                           "without algorithmic RIDs is chosen.\n"));
01073                 DEBUGADD(0, ("Please map all used groups using 'net groupmap "
01074                              "add', set the maximum used RID using\n"));
01075                 DEBUGADD(0, ("'net setmaxrid' and remove the parameter\n"));
01076                 return False;
01077         }
01078 
01079         if ( (ctx = talloc_init("pdb_new_rid")) == NULL ) {
01080                 DEBUG(0,("pdb_new_rid: Talloc initialization failure\n"));
01081                 return False;
01082         }
01083 
01084         /* Attempt to get an unused RID (max tires is 250...yes that it is 
01085            and arbitrary number I pulkled out of my head).   -- jerry */
01086 
01087         for ( i=0; allocated_rid==0 && i<250; i++ ) {
01088                 /* get a new RID */
01089 
01090                 if ( !pdb->new_rid(pdb, &allocated_rid) ) {
01091                         return False;
01092                 }
01093 
01094                 /* validate that the RID is not in use */
01095 
01096                 if ( lookup_global_sam_rid( ctx, allocated_rid, &name, &type, NULL ) ) {
01097                         allocated_rid = 0;
01098                 }
01099         }
01100 
01101         TALLOC_FREE( ctx );
01102 
01103         if ( allocated_rid == 0 ) {
01104                 DEBUG(0,("pdb_new_rid: Failed to find unused RID\n"));
01105                 return False;
01106         }
01107 
01108         *rid = allocated_rid;
01109 
01110         return True;
01111 }
01112 
01113 /***************************************************************
01114   Initialize the static context (at smbd startup etc). 
01115 
01116   If uninitialised, context will auto-init on first use.
01117  ***************************************************************/
01118 
01119 BOOL initialize_password_db(BOOL reload)
01120 {       
01121         return (pdb_get_methods_reload(reload) != NULL);
01122 }
01123 
01124 
01125 /***************************************************************************
01126   Default implementations of some functions.
01127  ****************************************************************************/
01128 
01129 static NTSTATUS pdb_default_getsampwnam (struct pdb_methods *methods, struct samu *user, const char *sname)
01130 {
01131         return NT_STATUS_NO_SUCH_USER;
01132 }
01133 
01134 static NTSTATUS pdb_default_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const DOM_SID *sid)
01135 {
01136         return NT_STATUS_NO_SUCH_USER;
01137 }
01138 
01139 static NTSTATUS pdb_default_add_sam_account (struct pdb_methods *methods, struct samu *newpwd)
01140 {
01141         return NT_STATUS_NOT_IMPLEMENTED;
01142 }
01143 
01144 static NTSTATUS pdb_default_update_sam_account (struct pdb_methods *methods, struct samu *newpwd)
01145 {
01146         return NT_STATUS_NOT_IMPLEMENTED;
01147 }
01148 
01149 static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, struct samu *pwd)
01150 {
01151         return NT_STATUS_NOT_IMPLEMENTED;
01152 }
01153 
01154 static NTSTATUS pdb_default_rename_sam_account (struct pdb_methods *methods, struct samu *pwd, const char *newname)
01155 {
01156         return NT_STATUS_NOT_IMPLEMENTED;
01157 }
01158 
01159 static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, struct samu *newpwd, BOOL success)
01160 {
01161         return NT_STATUS_OK;
01162 }
01163 
01164 static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update, uint32 acb_mask)
01165 {
01166         return NT_STATUS_NOT_IMPLEMENTED;
01167 }
01168 
01169 static NTSTATUS pdb_default_getsampwent(struct pdb_methods *methods, struct samu *user)
01170 {
01171         return NT_STATUS_NOT_IMPLEMENTED;
01172 }
01173 
01174 static void pdb_default_endsampwent(struct pdb_methods *methods)
01175 {
01176         return; /* NT_STATUS_NOT_IMPLEMENTED; */
01177 }
01178 
01179 static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
01180 {
01181         return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
01182 }
01183 
01184 static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
01185 {
01186         return account_policy_set(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
01187 }
01188 
01189 static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num)
01190 {
01191         *seq_num = time(NULL);
01192         return NT_STATUS_OK;
01193 }
01194 
01195 static BOOL pdb_default_uid_to_sid(struct pdb_methods *methods, uid_t uid,
01196                                    DOM_SID *sid)
01197 {
01198         struct samu *sampw = NULL;
01199         struct passwd *unix_pw;
01200         BOOL ret;
01201         
01202         unix_pw = sys_getpwuid( uid );
01203 
01204         if ( !unix_pw ) {
01205                 DEBUG(4,("pdb_default_uid_to_rid: host has no idea of uid "
01206                          "%lu\n", (unsigned long)uid));
01207                 return False;
01208         }
01209         
01210         if ( !(sampw = samu_new( NULL )) ) {
01211                 DEBUG(0,("pdb_default_uid_to_rid: samu_new() failed!\n"));
01212                 return False;
01213         }
01214 
01215         become_root();
01216         ret = NT_STATUS_IS_OK(
01217                 methods->getsampwnam(methods, sampw, unix_pw->pw_name ));
01218         unbecome_root();
01219 
01220         if (!ret) {
01221                 DEBUG(5, ("pdb_default_uid_to_rid: Did not find user "
01222                           "%s (%d)\n", unix_pw->pw_name, uid));
01223                 TALLOC_FREE(sampw);
01224                 return False;
01225         }
01226 
01227         sid_copy(sid, pdb_get_user_sid(sampw));
01228 
01229         TALLOC_FREE(sampw);
01230 
01231         return True;
01232 }
01233 
01234 static BOOL pdb_default_uid_to_rid(struct pdb_methods *methods, uid_t uid,
01235                                    uint32 *rid)
01236 {
01237         DOM_SID sid;
01238         BOOL ret;
01239 
01240         ret = pdb_default_uid_to_sid(methods, uid, &sid);
01241         if (!ret) {
01242                 return ret;
01243         }
01244         
01245         ret = sid_peek_check_rid(get_global_sam_sid(), &sid, rid);
01246 
01247         if (!ret) {
01248                 DEBUG(1, ("Could not peek rid out of sid %s\n",
01249                           sid_string_static(&sid)));
01250         }
01251 
01252         return ret;
01253 }
01254 
01255 static BOOL pdb_default_gid_to_sid(struct pdb_methods *methods, gid_t gid,
01256                                    DOM_SID *sid)
01257 {
01258         GROUP_MAP map;
01259 
01260         if (!NT_STATUS_IS_OK(methods->getgrgid(methods, &map, gid))) {
01261                 return False;
01262         }
01263 
01264         sid_copy(sid, &map.sid);
01265         return True;
01266 }
01267 
01268 static BOOL pdb_default_sid_to_id(struct pdb_methods *methods,
01269                                   const DOM_SID *sid,
01270                                   union unid_t *id, enum lsa_SidType *type)
01271 {
01272         TALLOC_CTX *mem_ctx;
01273         BOOL ret = False;
01274         const char *name;
01275         uint32 rid;
01276 
01277         mem_ctx = talloc_new(NULL);
01278 
01279         if (mem_ctx == NULL) {
01280                 DEBUG(0, ("talloc_new failed\n"));
01281                 return False;
01282         }
01283 
01284         if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) {
01285                 /* Here we might have users as well as groups and aliases */
01286                 ret = lookup_global_sam_rid(mem_ctx, rid, &name, type, id);
01287                 goto done;
01288         }
01289 
01290         /* check for "Unix User" */
01291 
01292         if ( sid_peek_check_rid(&global_sid_Unix_Users, sid, &rid) ) {
01293                 id->uid = rid;
01294                 *type = SID_NAME_USER;
01295                 ret = True;             
01296                 goto done;              
01297         }
01298         
01299         /* check for "Unix User" */
01300 
01301         if ( sid_peek_check_rid(&global_sid_Unix_Groups, sid, &rid) ) {
01302                 id->gid = rid;
01303                 *type = SID_NAME_ALIAS;
01304                 ret = True;             
01305                 goto done;              
01306         }
01307         
01308 
01309         /* BUILTIN */
01310 
01311         if (sid_peek_check_rid(&global_sid_Builtin, sid, &rid)) {
01312                 /* Here we only have aliases */
01313                 GROUP_MAP map;
01314                 if (!NT_STATUS_IS_OK(methods->getgrsid(methods, &map, *sid))) {
01315                         DEBUG(10, ("Could not find map for sid %s\n",
01316                                    sid_string_static(sid)));
01317                         goto done;
01318                 }
01319                 if ((map.sid_name_use != SID_NAME_ALIAS) &&
01320                     (map.sid_name_use != SID_NAME_WKN_GRP)) {
01321                         DEBUG(10, ("Map for sid %s is a %s, expected an "
01322                                    "alias\n", sid_string_static(sid),
01323                                    sid_type_lookup(map.sid_name_use)));
01324                         goto done;
01325                 }
01326 
01327                 id->gid = map.gid;
01328                 *type = SID_NAME_ALIAS;
01329                 ret = True;
01330                 goto done;
01331         }
01332 
01333         DEBUG(5, ("Sid %s is neither ours, a Unix SID, nor builtin\n",
01334                   sid_string_static(sid)));
01335 
01336  done:
01337 
01338         TALLOC_FREE(mem_ctx);
01339         return ret;
01340 }
01341 
01342 static BOOL add_uid_to_array_unique(TALLOC_CTX *mem_ctx,
01343                                     uid_t uid, uid_t **pp_uids, size_t *p_num)
01344 {
01345         size_t i;
01346 
01347         for (i=0; i<*p_num; i++) {
01348                 if ((*pp_uids)[i] == uid)
01349                         return True;
01350         }
01351         
01352         *pp_uids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_uids, uid_t, *p_num+1);
01353 
01354         if (*pp_uids == NULL)
01355                 return False;
01356 
01357         (*pp_uids)[*p_num] = uid;
01358         *p_num += 1;
01359         return True;
01360 }
01361 
01362 static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size_t *p_num)
01363 {
01364         struct group *grp;
01365         char **gr;
01366         struct passwd *pwd;
01367         BOOL winbind_env;
01368         BOOL ret = False;
01369  
01370         *pp_uids = NULL;
01371         *p_num = 0;
01372 
01373         /* We only look at our own sam, so don't care about imported stuff */
01374         winbind_env = winbind_env_set();
01375         winbind_off();
01376 
01377         if ((grp = getgrgid(gid)) == NULL) {
01378                 /* allow winbindd lookups, but only if they weren't already disabled */
01379                 goto done;
01380         }
01381 
01382         /* Primary group members */
01383         setpwent();
01384         while ((pwd = getpwent()) != NULL) {
01385                 if (pwd->pw_gid == gid) {
01386                         if (!add_uid_to_array_unique(mem_ctx, pwd->pw_uid,
01387                                                 pp_uids, p_num)) {
01388                                 goto done;
01389                         }
01390                 }
01391         }
01392         endpwent();
01393 
01394         /* Secondary group members */
01395         for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
01396                 struct passwd *pw = getpwnam(*gr);
01397 
01398                 if (pw == NULL)
01399                         continue;
01400                 if (!add_uid_to_array_unique(mem_ctx, pw->pw_uid, pp_uids, p_num)) {
01401                         goto done;
01402                 }
01403         }
01404 
01405         ret = True;
01406 
01407   done:
01408 
01409         /* allow winbindd lookups, but only if they weren't already disabled */
01410         if (!winbind_env) {
01411                 winbind_on();
01412         }
01413         
01414         return ret;
01415 }
01416 
01417 static NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
01418                                         TALLOC_CTX *mem_ctx,
01419                                         const DOM_SID *group,
01420                                         uint32 **pp_member_rids,
01421                                         size_t *p_num_members)
01422 {
01423         gid_t gid;
01424         uid_t *uids;
01425         size_t i, num_uids;
01426 
01427         *pp_member_rids = NULL;
01428         *p_num_members = 0;
01429 
01430         if (!sid_to_gid(group, &gid))
01431                 return NT_STATUS_NO_SUCH_GROUP;
01432 
01433         if(!get_memberuids(mem_ctx, gid, &uids, &num_uids))
01434                 return NT_STATUS_NO_SUCH_GROUP;
01435 
01436         if (num_uids == 0)
01437                 return NT_STATUS_OK;
01438 
01439         *pp_member_rids = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_uids);
01440 
01441         for (i=0; i<num_uids; i++) {
01442                 DOM_SID sid;
01443 
01444                 uid_to_sid(&sid, uids[i]);
01445 
01446                 if (!sid_check_is_in_our_domain(&sid)) {
01447                         DEBUG(5, ("Inconsistent SAM -- group member uid not "
01448                                   "in our domain\n"));
01449                         continue;
01450                 }
01451 
01452                 sid_peek_rid(&sid, &(*pp_member_rids)[*p_num_members]);
01453                 *p_num_members += 1;
01454         }
01455 
01456         return NT_STATUS_OK;
01457 }
01458 
01459 static NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods,
01460                                             TALLOC_CTX *mem_ctx,
01461                                             struct samu *user,
01462                                             DOM_SID **pp_sids,
01463                                             gid_t **pp_gids,
01464                                             size_t *p_num_groups)
01465 {
01466         size_t i;
01467         gid_t gid;
01468         struct passwd *pw;
01469         const char *username = pdb_get_username(user);
01470         
01471 
01472         /* Ignore the primary group SID.  Honor the real Unix primary group.
01473            The primary group SID is only of real use to Windows clients */
01474            
01475         if ( !(pw = getpwnam_alloc(mem_ctx, username)) ) {
01476                 return NT_STATUS_NO_SUCH_USER;
01477         }
01478         
01479         gid = pw->pw_gid;
01480         
01481         TALLOC_FREE( pw );
01482 
01483         if (!getgroups_unix_user(mem_ctx, username, gid, pp_gids, p_num_groups)) {
01484                 return NT_STATUS_NO_SUCH_USER;
01485         }
01486 
01487         if (*p_num_groups == 0) {
01488                 smb_panic("primary group missing");
01489         }
01490 
01491         *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups);
01492 
01493         if (*pp_sids == NULL) {
01494                 TALLOC_FREE(*pp_gids);
01495                 return NT_STATUS_NO_MEMORY;
01496         }
01497 
01498         for (i=0; i<*p_num_groups; i++) {
01499                 gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]);
01500         }
01501 
01502         return NT_STATUS_OK;
01503 }
01504 
01505 /*******************************************************************
01506  Look up a rid in the SAM we're responsible for (i.e. passdb)
01507  ********************************************************************/
01508 
01509 static BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
01510                                   const char **name,
01511                                   enum lsa_SidType *psid_name_use,
01512                                   union unid_t *unix_id)
01513 {
01514         struct samu *sam_account = NULL;
01515         GROUP_MAP map;
01516         BOOL ret;
01517         DOM_SID sid;
01518 
01519         *psid_name_use = SID_NAME_UNKNOWN;
01520         
01521         DEBUG(5,("lookup_global_sam_rid: looking up RID %u.\n",
01522                  (unsigned int)rid));
01523 
01524         sid_copy(&sid, get_global_sam_sid());
01525         sid_append_rid(&sid, rid);
01526         
01527         /* see if the passdb can help us with the name of the user */
01528 
01529         if ( !(sam_account = samu_new( NULL )) ) {
01530                 return False;
01531         }
01532 
01533         /* BEING ROOT BLLOCK */
01534         become_root();
01535         if (pdb_getsampwsid(sam_account, &sid)) {
01536                 struct passwd *pw;
01537 
01538                 unbecome_root();                /* -----> EXIT BECOME_ROOT() */
01539                 *name = talloc_strdup(mem_ctx, pdb_get_username(sam_account));
01540                 if (!*name) {
01541                         TALLOC_FREE(sam_account);
01542                         return False;
01543                 }
01544 
01545                 *psid_name_use = SID_NAME_USER;
01546 
01547                 TALLOC_FREE(sam_account);
01548 
01549                 if (unix_id == NULL) {
01550                         return True;
01551                 }
01552 
01553                 pw = Get_Pwnam(*name);
01554                 if (pw == NULL) {
01555                         return False;
01556                 }
01557                 unix_id->uid = pw->pw_uid;
01558                 return True;
01559         }
01560         TALLOC_FREE(sam_account);
01561         
01562         ret = pdb_getgrsid(&map, sid);
01563         unbecome_root();
01564         /* END BECOME_ROOT BLOCK */
01565   
01566         /* do not resolve SIDs to a name unless there is a valid 
01567            gid associated with it */
01568                    
01569         if ( ret && (map.gid != (gid_t)-1) ) {
01570                 *name = talloc_strdup(mem_ctx, map.nt_name);
01571                 *psid_name_use = map.sid_name_use;
01572 
01573                 if ( unix_id ) {
01574                         unix_id->gid = map.gid;
01575                 }
01576 
01577                 return True;
01578         }
01579         
01580         /* Windows will always map RID 513 to something.  On a non-domain 
01581            controller, this gets mapped to SERVER\None. */
01582 
01583         if ( unix_id ) {
01584                 DEBUG(5, ("Can't find a unix id for an unmapped group\n"));
01585                 return False;
01586         }
01587         
01588         if ( rid == DOMAIN_GROUP_RID_USERS ) {
01589                 *name = talloc_strdup(mem_ctx, "None" );
01590                 *psid_name_use = SID_NAME_DOM_GRP;
01591                 
01592                 return True;
01593         }
01594 
01595         return False;
01596 }
01597 
01598 static NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
01599                                  const DOM_SID *domain_sid,
01600                                  int num_rids,
01601                                  uint32 *rids,
01602                                  const char **names,
01603                                  enum lsa_SidType *attrs)
01604 {
01605         int i;
01606         NTSTATUS result;
01607         BOOL have_mapped = False;
01608         BOOL have_unmapped = False;
01609 
01610         if (sid_check_is_builtin(domain_sid)) {
01611 
01612                 for (i=0; i<num_rids; i++) {
01613                         const char *name;
01614 
01615                         if (lookup_builtin_rid(names, rids[i], &name)) {
01616                                 attrs[i] = SID_NAME_ALIAS;
01617                                 names[i] = name;
01618                                 DEBUG(5,("lookup_rids: %s:%d\n",
01619                                          names[i], attrs[i]));
01620                                 have_mapped = True;
01621                         } else {
01622                                 have_unmapped = True;
01623                                 attrs[i] = SID_NAME_UNKNOWN;
01624                         }
01625                 }
01626                 goto done;
01627         }
01628 
01629         /* Should not happen, but better check once too many */
01630         if (!sid_check_is_domain(domain_sid)) {
01631                 return NT_STATUS_INVALID_HANDLE;
01632         }
01633 
01634         for (i = 0; i < num_rids; i++) {
01635                 const char *name;
01636 
01637                 if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i],
01638                                           NULL)) {
01639                         if (name == NULL) {
01640                                 return NT_STATUS_NO_MEMORY;
01641                         }
01642                         names[i] = name;
01643                         DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
01644                         have_mapped = True;
01645                 } else {
01646                         have_unmapped = True;
01647                         attrs[i] = SID_NAME_UNKNOWN;
01648                 }
01649         }
01650 
01651  done:
01652 
01653         result = NT_STATUS_NONE_MAPPED;
01654 
01655         if (have_mapped)
01656                 result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
01657 
01658         return result;
01659 }
01660 
01661 #if 0
01662 static NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
01663                                   const DOM_SID *domain_sid,
01664                                   int num_names,
01665                                   const char **names,
01666                                   uint32 *rids,
01667                                   enum lsa_SidType *attrs)
01668 {
01669         int i;
01670         NTSTATUS result;
01671         BOOL have_mapped = False;
01672         BOOL have_unmapped = False;
01673 
01674         if (sid_check_is_builtin(domain_sid)) {
01675 
01676                 for (i=0; i<num_names; i++) {
01677                         uint32 rid;
01678 
01679                         if (lookup_builtin_name(names[i], &rid)) {
01680                                 attrs[i] = SID_NAME_ALIAS;
01681                                 rids[i] = rid;
01682                                 DEBUG(5,("lookup_rids: %s:%d\n",
01683                                          names[i], attrs[i]));
01684                                 have_mapped = True;
01685                         } else {
01686                                 have_unmapped = True;
01687                                 attrs[i] = SID_NAME_UNKNOWN;
01688                         }
01689                 }
01690                 goto done;
01691         }
01692 
01693         /* Should not happen, but better check once too many */
01694         if (!sid_check_is_domain(domain_sid)) {
01695                 return NT_STATUS_INVALID_HANDLE;
01696         }
01697 
01698         for (i = 0; i < num_names; i++) {
01699                 if (lookup_global_sam_name(names[i], 0, &rids[i], &attrs[i])) {
01700                         DEBUG(5,("lookup_names: %s-> %d:%d\n", names[i],
01701                                  rids[i], attrs[i]));
01702                         have_mapped = True;
01703                 } else {
01704                         have_unmapped = True;
01705                         attrs[i] = SID_NAME_UNKNOWN;
01706                 }
01707         }
01708 
01709  done:
01710 
01711         result = NT_STATUS_NONE_MAPPED;
01712 
01713         if (have_mapped)
01714                 result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
01715 
01716         return result;
01717 }
01718 #endif
01719 
01720 static struct pdb_search *pdb_search_init(enum pdb_search_type type)
01721 {
01722         TALLOC_CTX *mem_ctx;
01723         struct pdb_search *result;
01724 
01725         mem_ctx = talloc_init("pdb_search");
01726         if (mem_ctx == NULL) {
01727                 DEBUG(0, ("talloc_init failed\n"));
01728                 return NULL;
01729         }
01730 
01731         result = TALLOC_P(mem_ctx, struct pdb_search);
01732         if (result == NULL) {
01733                 DEBUG(0, ("talloc failed\n"));
01734                 return NULL;
01735         }
01736 
01737         result->mem_ctx = mem_ctx;
01738         result->type = type;
01739         result->cache = NULL;
01740         result->num_entries = 0;
01741         result->cache_size = 0;
01742         result->search_ended = False;
01743 
01744         /* Segfault appropriately if not initialized */
01745         result->next_entry = NULL;
01746         result->search_end = NULL;
01747 
01748         return result;
01749 }
01750 
01751 static void fill_displayentry(TALLOC_CTX *mem_ctx, uint32 rid,
01752                               uint16 acct_flags,
01753                               const char *account_name,
01754                               const char *fullname,
01755                               const char *description,
01756                               struct samr_displayentry *entry)
01757 {
01758         entry->rid = rid;
01759         entry->acct_flags = acct_flags;
01760 
01761         if (account_name != NULL)
01762                 entry->account_name = talloc_strdup(mem_ctx, account_name);
01763         else
01764                 entry->account_name = "";
01765 
01766         if (fullname != NULL)
01767                 entry->fullname = talloc_strdup(mem_ctx, fullname);
01768         else
01769                 entry->fullname = "";
01770 
01771         if (description != NULL)
01772                 entry->description = talloc_strdup(mem_ctx, description);
01773         else
01774                 entry->description = "";
01775 }
01776 
01777 static BOOL user_search_in_progress = False;
01778 struct user_search {
01779         uint16 acct_flags;
01780 };
01781 
01782 static BOOL next_entry_users(struct pdb_search *s,
01783                              struct samr_displayentry *entry)
01784 {
01785         struct user_search *state = (struct user_search *)s->private_data;
01786         struct samu *user = NULL;
01787 
01788  next:
01789         if ( !(user = samu_new( NULL )) ) {
01790                 DEBUG(0, ("next_entry_users: samu_new() failed!\n"));
01791                 return False;
01792         }
01793 
01794         if (!pdb_getsampwent(user)) {
01795                 TALLOC_FREE(user);
01796                 return False;
01797         }
01798 
01799         if ((state->acct_flags != 0) &&
01800             ((pdb_get_acct_ctrl(user) & state->acct_flags) == 0)) {
01801                 TALLOC_FREE(user);
01802                 goto next;
01803         }
01804 
01805         fill_displayentry(s->mem_ctx, pdb_get_user_rid(user),
01806                           pdb_get_acct_ctrl(user), pdb_get_username(user),
01807                           pdb_get_fullname(user), pdb_get_acct_desc(user),
01808                           entry);
01809 
01810         TALLOC_FREE(user);
01811         return True;
01812 }
01813 
01814 static void search_end_users(struct pdb_search *search)
01815 {
01816         pdb_endsampwent();
01817         user_search_in_progress = False;
01818 }
01819 
01820 static BOOL pdb_default_search_users(struct pdb_methods *methods,
01821                                      struct pdb_search *search,
01822                                      uint32 acct_flags)
01823 {
01824         struct user_search *state;
01825 
01826         if (user_search_in_progress) {
01827                 DEBUG(1, ("user search in progress\n"));
01828                 return False;
01829         }
01830 
01831         if (!pdb_setsampwent(False, acct_flags)) {
01832                 DEBUG(5, ("Could not start search\n"));
01833                 return False;
01834         }
01835 
01836         user_search_in_progress = True;
01837 
01838         state = TALLOC_P(search->mem_ctx, struct user_search);
01839         if (state == NULL) {
01840                 DEBUG(0, ("talloc failed\n"));
01841                 return False;
01842         }
01843 
01844         state->acct_flags = acct_flags;
01845 
01846         search->private_data = state;
01847         search->next_entry = next_entry_users;
01848         search->search_end = search_end_users;
01849         return True;
01850 }
01851 
01852 struct group_search {
01853         GROUP_MAP *groups;
01854         size_t num_groups, current_group;
01855 };
01856 
01857 static BOOL next_entry_groups(struct pdb_search *s,
01858                               struct samr_displayentry *entry)
01859 {
01860         struct group_search *state = (struct group_search *)s->private_data;
01861         uint32 rid;
01862         GROUP_MAP *map = &state->groups[state->current_group];
01863 
01864         if (state->current_group == state->num_groups)
01865                 return False;
01866 
01867         sid_peek_rid(&map->sid, &rid);
01868 
01869         fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
01870                           entry);
01871 
01872         state->current_group += 1;
01873         return True;
01874 }
01875 
01876 static void search_end_groups(struct pdb_search *search)
01877 {
01878         struct group_search *state =
01879                 (struct group_search *)search->private_data;
01880         SAFE_FREE(state->groups);
01881 }
01882 
01883 static BOOL pdb_search_grouptype(struct pdb_search *search,
01884                                  const DOM_SID *sid, enum lsa_SidType type)
01885 {
01886         struct group_search *state;
01887 
01888         state = TALLOC_P(search->mem_ctx, struct group_search);
01889         if (state == NULL) {
01890                 DEBUG(0, ("talloc failed\n"));
01891                 return False;
01892         }
01893 
01894         if (!pdb_enum_group_mapping(sid, type, &state->groups, &state->num_groups,
01895                                     True)) {
01896                 DEBUG(0, ("Could not enum groups\n"));
01897                 return False;
01898         }
01899 
01900         state->current_group = 0;
01901         search->private_data = state;
01902         search->next_entry = next_entry_groups;
01903         search->search_end = search_end_groups;
01904         return True;
01905 }
01906 
01907 static BOOL pdb_default_search_groups(struct pdb_methods *methods,
01908                                       struct pdb_search *search)
01909 {
01910         return pdb_search_grouptype(search, get_global_sam_sid(), SID_NAME_DOM_GRP);
01911 }
01912 
01913 static BOOL pdb_default_search_aliases(struct pdb_methods *methods,
01914                                        struct pdb_search *search,
01915                                        const DOM_SID *sid)
01916 {
01917 
01918         return pdb_search_grouptype(search, sid, SID_NAME_ALIAS);
01919 }
01920 
01921 static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
01922                                                      uint32 idx)
01923 {
01924         if (idx < search->num_entries)
01925                 return &search->cache[idx];
01926 
01927         if (search->search_ended)
01928                 return NULL;
01929 
01930         while (idx >= search->num_entries) {
01931                 struct samr_displayentry entry;
01932 
01933                 if (!search->next_entry(search, &entry)) {
01934                         search->search_end(search);
01935                         search->search_ended = True;
01936                         break;
01937                 }
01938 
01939                 ADD_TO_LARGE_ARRAY(search->mem_ctx, struct samr_displayentry,
01940                                    entry, &search->cache, &search->num_entries,
01941                                    &search->cache_size);
01942         }
01943 
01944         return (search->num_entries > idx) ? &search->cache[idx] : NULL;
01945 }
01946 
01947 struct pdb_search *pdb_search_users(uint32 acct_flags)
01948 {
01949         struct pdb_methods *pdb = pdb_get_methods();
01950         struct pdb_search *result;
01951 
01952         result = pdb_search_init(PDB_USER_SEARCH);
01953         if (result == NULL) {
01954                 return NULL;
01955         }
01956 
01957         if (!pdb->search_users(pdb, result, acct_flags)) {
01958                 talloc_destroy(result->mem_ctx);
01959                 return NULL;
01960         }
01961         return result;
01962 }
01963 
01964 struct pdb_search *pdb_search_groups(void)
01965 {
01966         struct pdb_methods *pdb = pdb_get_methods();
01967         struct pdb_search *result;
01968 
01969         result = pdb_search_init(PDB_GROUP_SEARCH);
01970         if (result == NULL) {
01971                  return NULL;
01972         }
01973 
01974         if (!pdb->search_groups(pdb, result)) {
01975                 talloc_destroy(result->mem_ctx);
01976                 return NULL;
01977         }
01978         return result;
01979 }
01980 
01981 struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
01982 {
01983         struct pdb_methods *pdb = pdb_get_methods();
01984         struct pdb_search *result;
01985 
01986         if (pdb == NULL) return NULL;
01987 
01988         result = pdb_search_init(PDB_ALIAS_SEARCH);
01989         if (result == NULL) return NULL;
01990 
01991         if (!pdb->search_aliases(pdb, result, sid)) {
01992                 talloc_destroy(result->mem_ctx);
01993                 return NULL;
01994         }
01995         return result;
01996 }
01997 
01998 uint32 pdb_search_entries(struct pdb_search *search,
01999                           uint32 start_idx, uint32 max_entries,
02000                           struct samr_displayentry **result)
02001 {
02002         struct samr_displayentry *end_entry;
02003         uint32 end_idx = start_idx+max_entries-1;
02004 
02005         /* The first entry needs to be searched after the last. Otherwise the
02006          * first entry might have moved due to a realloc during the search for
02007          * the last entry. */
02008 
02009         end_entry = pdb_search_getentry(search, end_idx);
02010         *result = pdb_search_getentry(search, start_idx);
02011 
02012         if (end_entry != NULL)
02013                 return max_entries;
02014 
02015         if (start_idx >= search->num_entries)
02016                 return 0;
02017 
02018         return search->num_entries - start_idx;
02019 }
02020 
02021 void pdb_search_destroy(struct pdb_search *search)
02022 {
02023         if (search == NULL)
02024                 return;
02025 
02026         if (!search->search_ended)
02027                 search->search_end(search);
02028 
02029         talloc_destroy(search->mem_ctx);
02030 }
02031 
02032 /*******************************************************************
02033  Create a pdb_methods structure and initialize it with the default
02034  operations.  In this way a passdb module can simply implement
02035  the functionality it cares about.  However, normally this is done 
02036  in groups of related functions.
02037 *******************************************************************/
02038 
02039 NTSTATUS make_pdb_method( struct pdb_methods **methods ) 
02040 {
02041         /* allocate memory for the structure as its own talloc CTX */
02042 
02043         if ( !(*methods = TALLOC_ZERO_P(NULL, struct pdb_methods) ) ) {
02044                 return NT_STATUS_NO_MEMORY;
02045         }
02046 
02047         (*methods)->setsampwent = pdb_default_setsampwent;
02048         (*methods)->endsampwent = pdb_default_endsampwent;
02049         (*methods)->getsampwent = pdb_default_getsampwent;
02050         (*methods)->getsampwnam = pdb_default_getsampwnam;
02051         (*methods)->getsampwsid = pdb_default_getsampwsid;
02052         (*methods)->create_user = pdb_default_create_user;
02053         (*methods)->delete_user = pdb_default_delete_user;
02054         (*methods)->add_sam_account = pdb_default_add_sam_account;
02055         (*methods)->update_sam_account = pdb_default_update_sam_account;
02056         (*methods)->delete_sam_account = pdb_default_delete_sam_account;
02057         (*methods)->rename_sam_account = pdb_default_rename_sam_account;
02058         (*methods)->update_login_attempts = pdb_default_update_login_attempts;
02059 
02060         (*methods)->getgrsid = pdb_default_getgrsid;
02061         (*methods)->getgrgid = pdb_default_getgrgid;
02062         (*methods)->getgrnam = pdb_default_getgrnam;
02063         (*methods)->create_dom_group = pdb_default_create_dom_group;
02064         (*methods)->delete_dom_group = pdb_default_delete_dom_group;
02065         (*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry;
02066         (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
02067         (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
02068         (*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
02069         (*methods)->enum_group_members = pdb_default_enum_group_members;
02070         (*methods)->enum_group_memberships = pdb_default_enum_group_memberships;
02071         (*methods)->set_unix_primary_group = pdb_default_set_unix_primary_group;
02072         (*methods)->add_groupmem = pdb_default_add_groupmem;
02073         (*methods)->del_groupmem = pdb_default_del_groupmem;
02074         (*methods)->find_alias = pdb_default_find_alias;
02075         (*methods)->create_alias = pdb_default_create_alias;
02076         (*methods)->delete_alias = pdb_default_delete_alias;
02077         (*methods)->get_aliasinfo = pdb_default_get_aliasinfo;
02078         (*methods)->set_aliasinfo = pdb_default_set_aliasinfo;
02079         (*methods)->add_aliasmem = pdb_default_add_aliasmem;
02080         (*methods)->del_aliasmem = pdb_default_del_aliasmem;
02081         (*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
02082         (*methods)->enum_alias_memberships = pdb_default_alias_memberships;
02083         (*methods)->lookup_rids = pdb_default_lookup_rids;
02084         (*methods)->get_account_policy = pdb_default_get_account_policy;
02085         (*methods)->set_account_policy = pdb_default_set_account_policy;
02086         (*methods)->get_seq_num = pdb_default_get_seq_num;
02087         (*methods)->uid_to_rid = pdb_default_uid_to_rid;
02088         (*methods)->uid_to_sid = pdb_default_uid_to_sid;
02089         (*methods)->gid_to_sid = pdb_default_gid_to_sid;
02090         (*methods)->sid_to_id = pdb_default_sid_to_id;
02091 
02092         (*methods)->search_users = pdb_default_search_users;
02093         (*methods)->search_groups = pdb_default_search_groups;
02094         (*methods)->search_aliases = pdb_default_search_aliases;
02095 
02096         return NT_STATUS_OK;
02097 }

Sambaに対してSat Aug 29 21:23:12 2009に生成されました。  doxygen 1.4.7