diff options
Diffstat (limited to 'source3/passdb/passdb.c')
-rw-r--r-- | source3/passdb/passdb.c | 430 |
1 files changed, 403 insertions, 27 deletions
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 9e5b3ef145..263bbe57cd 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -21,40 +21,34 @@ */ #include "includes.h" +#include "nterr.h" extern int DEBUGLEVEL; -/************************************************************************ - Routine to search sam passwd by name. -*************************************************************************/ +/********************************************************** + ********************************************************** -struct smb_passwd *getsampwnam(char *name) -{ -#ifdef USE_LDAP - return getldappwnam(name); -#else - return getsmbpwnam(name); -#endif /* USE_LDAP */ -} + low-level redirection routines: -/************************************************************************ - Routine to search sam passwd by uid. -*************************************************************************/ + startsampwent() + endsampwent() + getsampwent() + getsam21pwent() + getsampwpos() + setsampwpos() -struct smb_passwd *getsampwuid(unsigned int uid) -{ -#ifdef USE_LDAP - return getldappwuid(uid); -#else - return getsmbpwuid(uid); -#endif /* USE_LDAP */ -} + add_sampwd_entry() + mod_sampwd_entry() + add_sam21pwd_entry() + mod_sam21pwd_entry() + + ********************************************************** + **********************************************************/ /*************************************************************** Start to enumerate the sam passwd list. Returns a void pointer to ensure no modification outside this module. ****************************************************************/ - void *startsampwent(BOOL update) { #ifdef USE_LDAP @@ -67,7 +61,6 @@ void *startsampwent(BOOL update) /*************************************************************** End enumeration of the sam passwd list. ****************************************************************/ - void endsampwent(void *vp) { #ifdef USE_LDAP @@ -80,7 +73,6 @@ void endsampwent(void *vp) /************************************************************************* Routine to return the next entry in the sam passwd list. *************************************************************************/ - struct smb_passwd *getsampwent(void *vp) { #ifdef USE_LDAP @@ -91,6 +83,23 @@ struct smb_passwd *getsampwent(void *vp) } /************************************************************************* + Routine to return the next entry in the sam passwd list. + *************************************************************************/ +struct sam_passwd *getsam21pwent(void *vp) +{ +#if 0 +#ifdef USE_LDAP + return getldap21pwent(vp); +#else + return getsmb21pwent(vp); +#endif /* USE_LDAP */ +#else + DEBUG(0,("getsam21pwent: under development\n")); + return NULL; +#endif +} + +/************************************************************************* Return the current position in the sam passwd list as an unsigned long. This must be treated as an opaque token. *************************************************************************/ @@ -119,7 +128,6 @@ BOOL setsampwpos(void *vp, unsigned long tok) /************************************************************************ Routine to add an entry to the sam passwd file. *************************************************************************/ - BOOL add_sampwd_entry(struct smb_passwd *newpwd) { #ifdef USE_LDAP @@ -130,6 +138,23 @@ BOOL add_sampwd_entry(struct smb_passwd *newpwd) } /************************************************************************ + Routine to add an entry to the sam passwd file. +*************************************************************************/ +BOOL add_sam21pwd_entry(struct sam_passwd *newpwd) +{ +#if 0 +#ifdef USE_LDAP + return add_ldappwd_entry(newpwd); +#else + return add_smbpwd_entry(newpwd); +#endif /* USE_LDAP */ +#else + DEBUG(0,("add_sam21pwd_entry() - under development\n")); + return False; +#endif +} + +/************************************************************************ Routine to search the sam passwd file for an entry matching the username. and then modify its password entry. We can't use the startsampwent()/ getsampwent()/endsampwent() interfaces here as we depend on looking @@ -137,7 +162,6 @@ BOOL add_sampwd_entry(struct smb_passwd *newpwd) override = False, normal override = True, override XXXXXXXX'd out password or NO PASS ************************************************************************/ - BOOL mod_sampwd_entry(struct smb_passwd* pwd, BOOL override) { #ifdef USE_LDAP @@ -147,3 +171,355 @@ BOOL mod_sampwd_entry(struct smb_passwd* pwd, BOOL override) #endif /* USE_LDAP */ } +/************************************************************************ + Routine to search the sam passwd file for an entry matching the username. + and then modify its password entry. We can't use the startsampwent()/ + getsampwent()/endsampwent() interfaces here as we depend on looking + in the actual file to decide how much room we have to write data. + override = False, normal + override = True, override XXXXXXXX'd out password or NO PASS +************************************************************************/ +BOOL mod_sam21pwd_entry(struct sam_passwd* pwd, BOOL override) +{ +#if 0 +#ifdef USE_LDAP + return mod_ldappwd_entry(pwd, override); +#else + return mod_smbpwd_entry(pwd, override); +#endif /* USE_LDAP */ +#else + DEBUG(0,("mod_sam21pwd_entry() - under development\n")); + return False; +#endif +} + +/********************************************************** + ********************************************************** + + high-level database routines: + getsampwnam() + getsampwuid() + getsam21pwnam() + getsam21pwuid() + + ********************************************************** + **********************************************************/ + +/************************************************************************ + Routine to search sam passwd by name. +*************************************************************************/ +struct smb_passwd *getsampwnam(char *name) +{ + struct smb_passwd *pwd = NULL; + void *fp = NULL; + + DEBUG(10, ("getsampwnam: search by name: %s\n", name)); + + /* Open the sam password file - not for update. */ + fp = startsampwent(False); + + if (fp == NULL) + { + DEBUG(0, ("getsampwnam: unable to open sam password database.\n")); + return NULL; + } + + while ((pwd = getsampwent(fp)) != NULL && !strequal(pwd->smb_name, name)); + + if (pwd != NULL) + { + DEBUG(10, ("getsampwnam: found by name: %s\n", name)); + } + + endsampwent(fp); + return pwd; +} + +/************************************************************************ + Routine to search sam passwd by name. +*************************************************************************/ +struct sam_passwd *getsam21pwnam(char *name) +{ + struct sam_passwd *pwd = NULL; + void *fp = NULL; + + DEBUG(10, ("getsam21pwnam: search by name: %s\n", name)); + + /* Open the sam password file - not for update. */ + fp = startsampwent(False); + + if (fp == NULL) + { + DEBUG(0, ("getsam21pwnam: unable to open sam password database.\n")); + return NULL; + } + + while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->smb_name, name)); + + if (pwd != NULL) + { + DEBUG(10, ("getsam21pwnam: found by name: %s\n", name)); + } + + endsampwent(fp); + return pwd; +} + +/************************************************************************ + Routine to search sam passwd by uid. +*************************************************************************/ +struct smb_passwd *getsampwuid(uid_t smb_userid) +{ + struct smb_passwd *pwd = NULL; + void *fp = NULL; + + DEBUG(10, ("getsampwuid: search by smb_userid: %x\n", smb_userid)); + + /* Open the sam password file - not for update. */ + fp = startsampwent(False); + + if (fp == NULL) + { + DEBUG(0, ("getsampwuid: unable to open sam password database.\n")); + return NULL; + } + + while ((pwd = getsampwent(fp)) != NULL && pwd->smb_userid != smb_userid); + + if (pwd != NULL) + { + DEBUG(10, ("getsampwuid: found by smb_userid: %x\n", smb_userid)); + } + + endsmbpwent(fp); + return pwd; +} + +/************************************************************************ + Routine to search sam passwd by rid. +*************************************************************************/ +struct sam_passwd *getsam21pwrid(uint32 rid) +{ + struct sam_passwd *pwd = NULL; + void *fp = NULL; + + DEBUG(10, ("getsam21pwrid: search by rid: %x\n", rid)); + + /* Open the sam password file - not for update. */ + fp = startsampwent(False); + + if (fp == NULL) + { + DEBUG(0, ("getsam21pwrid: unable to open sam password database.\n")); + return NULL; + } + + while ((pwd = getsam21pwent(fp)) != NULL && pwd->user_rid != rid); + + if (pwd != NULL) + { + DEBUG(10, ("getsam21pwrid: found by smb_userid: %x\n", rid)); + } + + endsmbpwent(fp); + return pwd; +} + + +/********************************************************** + ********************************************************** + + utility routines which are likely to be useful to all password + databases + + ********************************************************** + **********************************************************/ + +/********************************************************** + Encode the account control bits into a string. + **********************************************************/ +char *encode_acct_ctrl(uint16 acct_ctrl) +{ + static fstring acct_str; + char *p = acct_str; + + *p++ = '['; + + if (acct_ctrl & ACB_HOMDIRREQ) *p++ = 'H'; + if (acct_ctrl & ACB_TEMPDUP ) *p++ = 'T'; + if (acct_ctrl & ACB_NORMAL ) *p++ = 'U'; + if (acct_ctrl & ACB_MNS ) *p++ = 'M'; + if (acct_ctrl & ACB_WSTRUST ) *p++ = 'W'; + if (acct_ctrl & ACB_SVRTRUST ) *p++ = 'S'; + if (acct_ctrl & ACB_AUTOLOCK ) *p++ = 'L'; + if (acct_ctrl & ACB_PWNOEXP ) *p++ = 'X'; + if (acct_ctrl & ACB_DOMTRUST ) *p++ = 'I'; + + *p++ = ']'; + *p = '\0'; + return acct_str; +} + +/********************************************************** + Decode the account control bits from a string. + + this function breaks coding standards minimum line width of 80 chars. + reason: vertical line-up code clarity - all case statements fit into + 15 lines, which is more important. + **********************************************************/ +uint16 decode_acct_ctrl(char *p) +{ + uint16 acct_ctrl = 0; + BOOL finished = False; + + /* + * Check if the account type bits have been encoded after the + * NT password (in the form [NDHTUWSLXI]). + */ + + if (*p != '[') return 0; + + for (p++; *p && !finished; p++) + { + switch (*p) + { +#if 0 + /* + * Hmmm. Don't allow these to be set/read independently + * of the actual password fields. We don't want a mismatch. + * JRA. + */ + case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ } + case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ } +#endif + case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ } + case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ } + case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ } + case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ } + case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ } + case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } + case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } + case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ } + case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ } + + case ':': + case '\n': + case '\0': + case ']': + default: { finished = True; } + } + } + + return acct_ctrl; +} + +/************************************************************* + Routine to get the next 32 hex characters and turn them + into a 16 byte array. +**************************************************************/ +int gethexpwd(char *p, char *pwd) +{ + int i; + unsigned char lonybble, hinybble; + char *hexchars = "0123456789ABCDEF"; + char *p1, *p2; + + for (i = 0; i < 32; i += 2) { + hinybble = toupper(p[i]); + lonybble = toupper(p[i + 1]); + + p1 = strchr(hexchars, hinybble); + p2 = strchr(hexchars, lonybble); + if (!p1 || !p2) + return (False); + hinybble = PTR_DIFF(p1, hexchars); + lonybble = PTR_DIFF(p2, hexchars); + + pwd[i / 2] = (hinybble << 4) | lonybble; + } + return (True); +} + +/******************************************************************* + Group and User RID username mapping function + ********************************************************************/ +BOOL name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid) +{ + struct passwd *pw = Get_Pwnam(user_name, False); + + if (u_rid == NULL || g_rid == NULL || user_name == NULL) + { + return False; + } + + if (!pw) + { + DEBUG(1,("Username %s is invalid on this system\n", user_name)); + return False; + } + + if (user_in_list(user_name, lp_domain_guest_users())) + { + *u_rid = DOMAIN_USER_RID_GUEST; + } + else if (user_in_list(user_name, lp_domain_admin_users())) + { + *u_rid = DOMAIN_USER_RID_ADMIN; + } + else + { + /* turn the unix UID into a Domain RID. this is what the posix + sub-system does (adds 1000 to the uid) */ + *u_rid = uid_to_user_rid(pw->pw_uid); + } + + /* absolutely no idea what to do about the unix GID to Domain RID mapping */ + *g_rid = gid_to_group_rid(pw->pw_gid); + + return True; +} + +/******************************************************************* + XXXX THIS FUNCTION SHOULD NOT BE HERE: IT SHOULD BE A STATIC FUNCTION + INSIDE smbpass.c + + converts NT User RID to a UNIX uid. + ********************************************************************/ +uid_t user_rid_to_uid(uint32 u_rid) +{ + return (uid_t)(u_rid - 1000); +} + +/******************************************************************* + XXXX THIS FUNCTION SHOULD NOT BE HERE: IT SHOULD BE A STATIC FUNCTION + INSIDE smbpass.c + + converts NT Group RID to a UNIX uid. + ********************************************************************/ +uid_t group_rid_to_uid(uint32 u_gid) +{ + return (uid_t)(u_gid - 1000); +} + +/******************************************************************* + XXXX THIS FUNCTION SHOULD NOT BE HERE: IT SHOULD BE A STATIC FUNCTION + INSIDE smbpass.c + + converts UNIX uid to an NT User RID. + ********************************************************************/ +uint32 uid_to_user_rid(uint32 uid) +{ + return (uint32)(uid + 1000); +} + +/******************************************************************* + XXXX THIS FUNCTION SHOULD NOT BE HERE: IT SHOULD BE A STATIC FUNCTION + INSIDE smbpass.c + + converts NT Group RID to a UNIX uid. + ********************************************************************/ +uint32 gid_to_group_rid(uint32 gid) +{ + return (uint32)(gid + 1000); +} + |