diff options
author | Luke Leighton <lkcl@samba.org> | 1998-11-29 20:06:52 +0000 |
---|---|---|
committer | Luke Leighton <lkcl@samba.org> | 1998-11-29 20:06:52 +0000 |
commit | 53373894acfff45885caf1e19a54141546ba5eea (patch) | |
tree | 7c4de230aa7357723f2858589142beed12f02156 /source3/passdb/sampassdb.c | |
parent | 30038de4623bc827ee8019c569faf00583d1fe58 (diff) | |
download | samba-53373894acfff45885caf1e19a54141546ba5eea.tar.gz samba-53373894acfff45885caf1e19a54141546ba5eea.tar.bz2 samba-53373894acfff45885caf1e19a54141546ba5eea.zip |
"retired" two modules to preserve their cvs history.
added their replacements, added sam password database API modules
(This used to be commit b1d1c1337c69c6f6bf25ab932a1a6a757e3ea2ae)
Diffstat (limited to 'source3/passdb/sampassdb.c')
-rw-r--r-- | source3/passdb/sampassdb.c | 515 |
1 files changed, 515 insertions, 0 deletions
diff --git a/source3/passdb/sampassdb.c b/source3/passdb/sampassdb.c new file mode 100644 index 0000000000..95055ed298 --- /dev/null +++ b/source3/passdb/sampassdb.c @@ -0,0 +1,515 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Password and authentication handling + Copyright (C) Jeremy Allison 1996-1998 + Copyright (C) Luke Kenneth Casson Leighton 1996-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "nterr.h" + +extern int DEBUGLEVEL; +extern DOM_SID global_sam_sid; + +/* + * NOTE. All these functions are abstracted into a structure + * that points to the correct function for the selected database. JRA. + * + * NOTE. for the get/mod/add functions, there are two sets of functions. + * one supports struct sam_passwd, the other supports struct smb_passwd. + * for speed optimisation it is best to support both these sets. + * + * it is, however, optional to support one set but not the other: there + * is conversion-capability built in to passdb.c, and run-time error + * detection for when neither are supported. + * + * password database writers are recommended to implement the sam_passwd + * functions in a first pass, as struct sam_passwd contains more + * information, needed by the NT Domain support. + * + * an API writer is expected to create either one set (struct smb_passwd) or + * the other (struct sam_passwd) OR both, and optionally also to write display + * info routines * (struct sam_disp_info). functions which the API writer + * chooses NOT to write must be wrapped in conversion functions (pwdb_x_to_y) + * such that API users can call any function and still get valid results. + * + * the password API does NOT fill in the gaps if you set an API function + * to NULL: it will deliberately attempt to call the NULL function. + * + */ + +static struct sam_passdb_ops *pwdb_ops; + +/*************************************************************** + Initialise the password db operations. +***************************************************************/ + +BOOL initialise_sam_password_db(void) +{ + if (pwdb_ops) + { + return True; + } + +#ifdef WITH_NISPLUS + pwdb_ops = nisplus_initialise_sam_password_db(); +#elif defined(WITH_LDAP) + pwdb_ops = ldap_initialise_sam_password_db(); +#elif defined(USE_SMBPASS_DB) + pwdb_ops = file_initialise_sam_password_db(); +#endif + + return (pwdb_ops != NULL); +} + +/* + * Functions that return/manipulate a struct sam_passwd. + */ + +/*************************************************************** + Start to enumerate the smb or sam passwd list. Returns a void pointer + to ensure no modification outside this module. + + Note that currently it is being assumed that a pointer returned + from this function may be used to enumerate struct sam_passwd + entries as well as struct smb_passwd entries. This may need + to change. JRA. + +****************************************************************/ + +void *startsam21pwent(BOOL update) +{ + return pwdb_ops->startsam21pwent(update); +} + +/*************************************************************** + End enumeration of the sam passwd list. + + Note that currently it is being assumed that a pointer returned + from this function may be used to enumerate struct sam_passwd + entries as well as struct smb_passwd entries. This may need + to change. JRA. + +****************************************************************/ + +void endsam21pwent(void *vp) +{ + pwdb_ops->endsam21pwent(vp); +} + +/************************************************************************* + Routine to return the next entry in the smb passwd list. + *************************************************************************/ + +struct sam_passwd *getsam21pwent(void *vp) +{ + return pwdb_sam_map_names(pwdb_ops->getsam21pwent(vp)); +} + +/************************************************************************ + Utility function to search sam passwd by name. use this if your database + does not have search facilities. +*************************************************************************/ + +struct sam_passwd *iterate_getsam21pwntnam(const char *name) +{ + struct sam_passwd *pwd = NULL; + void *fp = NULL; + + DEBUG(10, ("search by name: %s\n", name)); + + /* Open the smb password database - not for update. */ + fp = startsmbpwent(False); + + if (fp == NULL) + { + DEBUG(0, ("unable to open sam password database.\n")); + return NULL; + } + + while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->nt_name, name)) + { + DEBUG(10, ("iterate: %s 0x%x\n", pwd->nt_name, pwd->user_rid)); + } + + if (pwd != NULL) + { + DEBUG(10, ("found by name: %s\n", name)); + } + + endsmbpwent(fp); + return pwd; +} + +/************************************************************************ + Utility function to search sam passwd by rid. use this if your database + does not have search facilities. + + search capability by both rid and uid are needed as the rid <-> uid + mapping may be non-monotonic. + +*************************************************************************/ + +struct sam_passwd *iterate_getsam21pwrid(uint32 rid) +{ + struct sam_passwd *pwd = NULL; + void *fp = NULL; + + DEBUG(10, ("search by rid: %x\n", rid)); + + /* Open the smb password file - not for update. */ + fp = startsmbpwent(False); + + if (fp == NULL) + { + DEBUG(0, ("unable to open sam password database.\n")); + return NULL; + } + + while ((pwd = getsam21pwent(fp)) != NULL && pwd->user_rid != rid) + { + DEBUG(10, ("iterate: %s 0x%x\n", pwd->nt_name, pwd->user_rid)); + } + + if (pwd != NULL) + { + DEBUG(10, ("found by user_rid: %x\n", rid)); + } + + endsmbpwent(fp); + return pwd; +} + +/************************************************************************ + Utility function to search sam passwd by uid. use this if your database + does not have search facilities. + + search capability by both rid and uid are needed as the rid <-> uid + mapping may be non-monotonic. + +*************************************************************************/ + +struct sam_passwd *iterate_getsam21pwuid(uid_t uid) +{ + struct sam_passwd *pwd = NULL; + void *fp = NULL; + + DEBUG(10, ("search by uid: %x\n", (int)uid)); + + /* Open the smb password file - not for update. */ + fp = startsmbpwent(False); + + if (fp == NULL) + { + DEBUG(0, ("unable to open sam password database.\n")); + return NULL; + } + + while ((pwd = getsam21pwent(fp)) != NULL && pwd->unix_uid != uid) + { + } + + if (pwd != NULL) + { + DEBUG(10, ("found by unix_uid: %x\n", (int)uid)); + } + + endsmbpwent(fp); + return pwd; +} + +/************************************************************************* + Routine to return a display info structure, by rid + *************************************************************************/ +struct sam_disp_info *getsamdisprid(uint32 rid) +{ + return pwdb_ops->getsamdisprid(rid); +} + +/************************************************************************ + Routine to search sam passwd by name. +*************************************************************************/ + +struct sam_passwd *getsam21pwntnam(const char *name) +{ + return pwdb_sam_map_names(pwdb_ops->getsam21pwntnam(name)); +} + +/************************************************************************ + Routine to search sam passwd by rid. +*************************************************************************/ + +struct sam_passwd *getsam21pwrid(uint32 rid) +{ + return pwdb_sam_map_names(pwdb_ops->getsam21pwrid(rid)); +} + + +/********************************************************** + ********************************************************** + + utility routines which are likely to be useful to all password + databases + + ********************************************************** + **********************************************************/ + +/************************************************************* + initialises a struct sam_disp_info. + **************************************************************/ + +static void pwdb_init_dispinfo(struct sam_disp_info *user) +{ + if (user == NULL) return; + bzero(user, sizeof(*user)); + user->user_rid = 0xffffffff; +} + +/************************************************************* + initialises a struct sam_passwd. + **************************************************************/ +void pwdb_init_sam(struct sam_passwd *user) +{ + if (user == NULL) return; + bzero(user, sizeof(*user)); + unix_to_nt_time(&user->logon_time , (time_t)-1); + unix_to_nt_time(&user->logoff_time , (time_t)-1); + unix_to_nt_time(&user->kickoff_time , (time_t)-1); + unix_to_nt_time(&user->pass_last_set_time , (time_t)-1); + unix_to_nt_time(&user->pass_can_change_time , (time_t)-1); + unix_to_nt_time(&user->pass_must_change_time , (time_t)-1); + + user->unix_uid = (uid_t)-1; + user->unix_gid = (gid_t)-1; + user->user_rid = 0xffffffff; + user->group_rid = 0xffffffff; +} + +/************************************************************************* + Routine to return the next entry in the sam passwd list. + *************************************************************************/ + +struct sam_disp_info *pwdb_sam_to_dispinfo(struct sam_passwd *user) +{ + static struct sam_disp_info disp_info; + + if (user == NULL) return NULL; + + pwdb_init_dispinfo(&disp_info); + + disp_info.nt_name = user->nt_name; + disp_info.full_name = user->full_name; + disp_info.user_rid = user->user_rid; + + return &disp_info; +} + +/************************************************************* + converts a sam_passwd structure to a smb_passwd structure. + **************************************************************/ + +struct smb_passwd *pwdb_sam_to_smb(struct sam_passwd *user) +{ + static struct smb_passwd pw_buf; + static fstring nt_name; + static fstring unix_name; + + if (user == NULL) return NULL; + + pwdb_init_smb(&pw_buf); + + fstrcpy(nt_name , user->nt_name); + fstrcpy(unix_name, user->unix_name); + pw_buf.nt_name = nt_name; + pw_buf.unix_name = unix_name; + pw_buf.unix_uid = user->unix_uid; + pw_buf.user_rid = user->user_rid; + pw_buf.smb_passwd = user->smb_passwd; + pw_buf.smb_nt_passwd = user->smb_nt_passwd; + pw_buf.acct_ctrl = user->acct_ctrl; + pw_buf.pass_last_set_time = nt_time_to_unix(&user->pass_last_set_time); + + return &pw_buf; +} + + +/************************************************************* + converts a smb_passwd structure to a sam_passwd structure. + **************************************************************/ + +struct sam_passwd *pwdb_smb_to_sam(struct smb_passwd *user) +{ + static struct sam_passwd pw_buf; + static fstring nt_name; + static fstring unix_name; + + if (user == NULL) return NULL; + + pwdb_init_sam(&pw_buf); + + fstrcpy(nt_name , user->nt_name); + fstrcpy(unix_name, user->unix_name); + pw_buf.nt_name = nt_name; + pw_buf.unix_name = unix_name; + pw_buf.unix_uid = user->unix_uid; + pw_buf.user_rid = user->user_rid; + pw_buf.smb_passwd = user->smb_passwd; + pw_buf.smb_nt_passwd = user->smb_nt_passwd; + pw_buf.acct_ctrl = user->acct_ctrl; + unix_to_nt_time(&pw_buf.pass_last_set_time, user->pass_last_set_time); + + return &pw_buf; +} + +static BOOL trust_account_warning_done = False; + +/************************************************************* + fills in missing details. one set of details _must_ exist. + **************************************************************/ +struct sam_passwd *pwdb_sam_map_names(struct sam_passwd *sam) +{ + DOM_NAME_MAP gmep; + BOOL found = False; + DOM_SID sid; + static fstring unix_name; + static fstring nt_name; + + DEBUG(10,("pwdb_sam_map_names\n")); + + /* + * name details + */ + + if (sam == NULL) + { + return NULL; + } + + if (!found && sam->unix_name != NULL) + { + found = lookupsmbpwnam(sam->unix_name, &gmep); + } + if (!found && sam->unix_uid != (uid_t)-1) + { + found = lookupsmbpwuid(sam->unix_uid , &gmep); + } + if (!found && sam->user_rid != 0xffffffff) + { + sid_copy(&sid, &global_sam_sid); + sid_append_rid(&sid, sam->user_rid); + found = lookupsmbpwsid (&sid , &gmep); + } + if (!found && sam->nt_name != NULL) + { + found = lookupsmbpwntnam(sam->nt_name, &gmep); + } + + if (!found) + { + return NULL; + } + + if (!sid_front_equal(&global_sam_sid, &gmep.sid)) + { + return NULL; + } + + fstrcpy(unix_name, gmep.unix_name); + fstrcpy(nt_name , gmep.nt_name ); + if (sam->unix_name == NULL ) sam->unix_name = unix_name; + if (sam->nt_name == NULL ) sam->nt_name = nt_name ; + if (sam->unix_uid == (uid_t)-1 ) sam->unix_uid = (uid_t)gmep.unix_id; + if (sam->user_rid == 0xffffffff) sid_split_rid(&gmep.sid, &sam->user_rid); + + /* + * group details + */ + + found = False; + + if (sam->unix_gid != (gid_t)-1 && sam->group_rid != 0xffffffff) + { + return sam; + } + + if (sam->unix_gid == (gid_t)-1 && sam->group_rid == 0xffffffff) + { + struct passwd *pass = getpwnam(unix_name); + if (pass != NULL) + { + sam->unix_gid = pass->pw_gid; + } + else + { + DEBUG(0,("pwdb_sam_map_names: no unix password entry for %s\n", + unix_name)); + } + } + + if (!found && sam->unix_gid != (gid_t)-1) + { + found = lookupsmbgrpgid(sam->unix_gid , &gmep); + } + if (!found && sam->group_rid != 0xffffffff) + { + sid_copy(&sid, &global_sam_sid); + sid_append_rid(&sid, sam->group_rid); + found = lookupsmbgrpsid(&sid , &gmep); + } + + if (!found) + { + if (IS_BITS_SET_SOME(sam->acct_ctrl, ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) + { + if (!trust_account_warning_done) + { + trust_account_warning_done = True; + DEBUG(0, ("\ +pwdb_sam_map_names: your unix password database appears to have difficulties\n\ +resolving trust account %s, probably because it ends in a '$'.\n\ +you will get this warning only once (for all trust accounts)\n", unix_name)); + } + /* + * oh, dear. + */ + if (sam->unix_gid != (gid_t)-1) + { + sam->unix_gid = (gid_t)-1; + } + sam->group_rid = DOMAIN_GROUP_RID_USERS; + + return sam; + } + else + { + DEBUG(0, ("pwdb_sam_map_names: could not find Primary Group for %s\n", + unix_name)); + return NULL; + } + } + + if (!sid_front_equal(&global_sam_sid, &gmep.sid)) + { + return NULL; + } + + if (sam->unix_gid == (gid_t)-1 ) sam->unix_gid = (gid_t)gmep.unix_id; + if (sam->group_rid == 0xffffffff) sid_split_rid(&gmep.sid, &sam->group_rid); + + return sam; +} |