summaryrefslogtreecommitdiffstats
path: root/source/passdb
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-09-25 20:21:21 +0000
committerJeremy Allison <jra@samba.org>2001-09-25 20:21:21 +0000
commit611bf806d569b70edabbc04a2f5408142370a550 (patch)
tree8ef5d2229676be9362ac8db186e6f3925085a657 /source/passdb
parent322ba52f71045002c6b969fb87932ee8b7d578c8 (diff)
downloadsamba-611bf806d569b70edabbc04a2f5408142370a550.tar.gz
samba-611bf806d569b70edabbc04a2f5408142370a550.tar.xz
samba-611bf806d569b70edabbc04a2f5408142370a550.zip
Fixup passdb stuff to add new nisplus and ldap backends.
Jeremy.
Diffstat (limited to 'source/passdb')
-rw-r--r--source/passdb/passdb.c428
-rw-r--r--source/passdb/pdb_ldap.c1014
-rw-r--r--source/passdb/pdb_nisplus.c1401
-rw-r--r--source/passdb/pdb_smbpasswd.c34
-rw-r--r--source/passdb/pdb_tdb.c243
5 files changed, 2824 insertions, 296 deletions
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index 7d133fdda83..2ecbee274fc 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -2,7 +2,7 @@
Unix SMB/Netbios implementation.
Version 1.9.
Password and authentication handling
- Copyright (C) Jeremy Allison 1996-1998
+ Copyright (C) Jeremy Allison 1996-2001
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
Copyright (C) Gerald (Jerry) Carter 2000-2001
@@ -35,62 +35,29 @@ extern DOM_SID global_sam_sid;
struct passdb_ops *pdb_ops;
+#if 0 /* JERRY */
static void* pdb_handle = NULL;
+#endif
/***************************************************************
Initialize the password db operations.
***************************************************************/
+
BOOL initialize_password_db(BOOL reload)
-{
- /* This function is unfinished right now, so just
- ignore the details and always return True. It is here
- only as a placeholder --jerry */
+{
+ /*
+ * This function is unfinished right now, so just
+ * ignore the details and always return True. It
+ * is here only as a placeholder --jerry
+ */
return True;
-
-#if _NOT_YET_
- char* modulename = lp_passdb_module_path();
- /* load another module? */
- if (reload && pdb_handle)
- {
- sys_dlclose (pdb_handle);
- pdb_handle = NULL;
- }
-
- /* do we have a module defined or use the default? */
- if (strlen (modulename) != 0)
- {
- if ((pdb_handle=sys_dlopen (modulename, RTLD_LAZY)) == NULL)
- {
- DEBUG(0,("initialize_password_db: ERROR - Unable to open passdb module \"%s\"!\n%s\n",
- modulename, sys_dlerror()));
- }
- else
- DEBUG(1,("initialize_password_db: passdb module \"%s\" loaded successfully\n", modulename));
- }
-
- /* either no module name defined or the one that was failed
- to open. Let's try the default */
- if (pdb_handle == NULL)
- {
- if ((pdb_handle=sys_dlopen ("libpdbfile.so", RTLD_LAZY)) == NULL)
- {
- DEBUG(0,("initialize_password_db: ERROR - Unable to open \"libpdbfile.so\" passdb module! No user authentication possible!\n%s\n",
- sys_dlerror()));
- return False;
- }
- else
- DEBUG(1,("initialize_password_db: passdb module \"libpdbfile.so\" loaded successfully\n"));
- }
-
-
- return (pdb_handle != NULL);
-#endif
}
/*************************************************************
- initialises a struct sam_disp_info.
+ Initialises a struct sam_disp_info.
**************************************************************/
+
static void pdb_init_dispinfo(struct sam_disp_info *user)
{
if (user == NULL)
@@ -99,8 +66,9 @@ static void pdb_init_dispinfo(struct sam_disp_info *user)
}
/*************************************************************
- alloc memory and initialises a struct sam_passwd.
+ Alloc memory and initialises a struct sam_passwd.
************************************************************/
+
BOOL pdb_init_sam(SAM_ACCOUNT **user)
{
if (*user != NULL) {
@@ -138,8 +106,9 @@ BOOL pdb_init_sam(SAM_ACCOUNT **user)
}
/************************************************************
- free the SAM_ACCOUNT and the NT/LM hashes.
+ Free the SAM_ACCOUNT and the NT/LM hashes.
***********************************************************/
+
BOOL pdb_free_sam(SAM_ACCOUNT *user)
{
if (user == NULL) {
@@ -158,7 +127,7 @@ BOOL pdb_free_sam(SAM_ACCOUNT *user)
}
/************************************************************
- reset the SAM_ACCOUNT and the NT/LM hashes.
+ Reset the SAM_ACCOUNT and the NT/LM hashes.
***********************************************************/
BOOL pdb_reset_sam(SAM_ACCOUNT *user)
@@ -169,7 +138,7 @@ BOOL pdb_reset_sam(SAM_ACCOUNT *user)
}
SAFE_FREE(user->nt_pw);
- SAFE_FREE(user->lm_pw);
+ SAFE_FREE(user->lm_pw);
ZERO_STRUCTP(user);
return True;
@@ -178,6 +147,7 @@ BOOL pdb_reset_sam(SAM_ACCOUNT *user)
/*************************************************************************
Routine to return the next entry in the sam passwd list.
*************************************************************************/
+
struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user)
{
static struct sam_disp_info disp_info;
@@ -194,20 +164,146 @@ struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user)
return &disp_info;
}
+/**********************************************************
+ Encode the account control bits into a string.
+ length = length of string to encode into (including terminating
+ null). length *MUST BE MORE THAN 2* !
+ **********************************************************/
+
+char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
+{
+ static fstring acct_str;
+ size_t i = 0;
+
+ acct_str[i++] = '[';
+
+ if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
+ if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
+ if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
+ if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
+ if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
+ if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
+ if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
+ if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
+ if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
+ if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
+ if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
+
+ for ( ; i < length - 2 ; i++ )
+ acct_str[i] = ' ';
+
+ i = length - 2;
+ acct_str[i++] = ']';
+ acct_str[i++] = '\0';
+
+ return acct_str;
+}
+
+/**********************************************************
+ Decode the account control bits from a string.
+ **********************************************************/
+
+uint16 pdb_decode_acct_ctrl(const 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) {
+ case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
+ case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
+ 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 ' ': { break; }
+ case ':':
+ case '\n':
+ case '\0':
+ case ']':
+ default: { finished = True; }
+ }
+ }
+
+ return acct_ctrl;
+}
+
+/*************************************************************
+ Routine to set 32 hex password characters from a 16 byte array.
+**************************************************************/
+
+void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl)
+{
+ if (pwd != NULL) {
+ int i;
+ for (i = 0; i < 16; i++)
+ slprintf(&p[i*2], 3, "%02X", pwd[i]);
+ } else {
+ if (acct_ctrl & ACB_PWNOTREQ)
+ safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
+ else
+ safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
+ }
+}
+
+/*************************************************************
+ Routine to get the 32 hex characters and turn them
+ into a 16 byte array.
+**************************************************************/
+
+BOOL pdb_gethexpwd(char *p, unsigned char *pwd)
+{
+ int i;
+ unsigned char lonybble, hinybble;
+ char *hexchars = "0123456789ABCDEF";
+ char *p1, *p2;
+
+ if (!p)
+ return (False);
+
+ 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 pdb_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)
- {
+ if (!pw) {
DEBUG(1,("Username %s is invalid on this system\n", user_name));
return False;
}
@@ -225,6 +321,7 @@ BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
/*******************************************************************
Converts NT user RID to a UNIX uid.
********************************************************************/
+
uid_t pdb_user_rid_to_uid(uint32 user_rid)
{
return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
@@ -269,6 +366,7 @@ static BOOL pdb_rid_is_well_known(uint32 rid)
/*******************************************************************
Decides if a RID is a user or group RID.
********************************************************************/
+
BOOL pdb_rid_is_user(uint32 rid)
{
/* lkcl i understand that NT attaches an enumeration to a RID
@@ -291,9 +389,9 @@ BOOL pdb_rid_is_user(uint32 rid)
/*******************************************************************
Convert a rid into a name. Used in the lookup SID rpc.
********************************************************************/
+
BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
{
-
BOOL is_user = pdb_rid_is_user(rid);
DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" :
@@ -341,10 +439,9 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
}
} else {
- gid_t gid=-1;
+ gid_t gid;
struct group *gr;
- GROUP_MAP map;
- DOM_SID sid;
+
/*
* Don't try to convert the rid to a name if running
* in appliance mode
@@ -353,30 +450,11 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
if (lp_hide_local_users())
return False;
- /*
- * First try the TDB. If the RID exists and is mapped to a unix group,
- * return the NT name and the type.
- */
-
- sid_copy(&sid, &global_sam_sid);
- sid_append_rid(&sid, rid);
- if (get_group_map_from_sid(sid, &map) && map.gid!=-1) {
- *psid_name_use = map.sid_name_use;
- fstrcpy(name, map.nt_name);
-
- DEBUG(5,("local_lookup_rid: found NT group %s mapped to Unix gid %u for rid %u\n",
- name, (unsigned int)map.gid, (unsigned int)rid ));
-
- if(!getgrgid(map.gid))
- return False;
- else
- return True;
- }
-
- *psid_name_use = SID_NAME_ALIAS;
gid = pdb_user_rid_to_gid(rid);
-
gr = getgrgid(gid);
+
+ *psid_name_use = SID_NAME_ALIAS;
+
DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid,
gr ? "succeeded" : "failed" ));
@@ -387,7 +465,8 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
fstrcpy( name, gr->gr_name);
- DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name, (unsigned int)rid ));
+ DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name,
+ (unsigned int)rid ));
}
return True;
@@ -441,27 +520,13 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
/*
* Maybe it was a group ?
*/
- GROUP_MAP map;
- struct group *grp = NULL;
-
- /* It can be a mapped group */
- if (get_group_map_from_ntname(user, &map) && map.gid!=-1) {
-
- grp=getgrgid(map.gid);
- if (!grp)
- return False;
+ struct group *grp = getgrnam(user);
- sid_copy(&local_sid, &map.sid);
- *psid_name_use = map.sid_name_use;
- } else {
- /* It wasn't mapped, it can be a Unix group */
- grp=getgrnam(user);
- if(!grp)
- return False;
+ if(!grp)
+ return False;
- sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
- *psid_name_use = SID_NAME_ALIAS;
- }
+ sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
+ *psid_name_use = SID_NAME_ALIAS;
}
sid_copy( psid, &local_sid);
@@ -472,6 +537,7 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
/****************************************************************************
Convert a uid to SID - locally.
****************************************************************************/
+
DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
{
extern DOM_SID global_sam_sid;
@@ -482,10 +548,10 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
return psid;
}
-
/****************************************************************************
Convert a SID to uid - locally.
****************************************************************************/
+
BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
{
extern DOM_SID global_sam_sid;
@@ -527,6 +593,7 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
/****************************************************************************
Convert a gid to SID - locally.
****************************************************************************/
+
DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
{
extern DOM_SID global_sam_sid;
@@ -540,6 +607,7 @@ DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
/****************************************************************************
Convert a SID to gid - locally.
****************************************************************************/
+
BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
{
extern DOM_SID global_sam_sid;
@@ -582,12 +650,13 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
static void select_name(pstring string, const UNISTR2 *from)
{
if (from->buffer != 0)
- unistr2_to_ascii(string, from, sizeof(string));
+ unistr2_to_ascii(string, from, sizeof(*string));
}
/*************************************************************
- copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
+ Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
**************************************************************/
+
void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
{
@@ -627,8 +696,9 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
}
/*************************************************************
- copies a sam passwd.
+ Copies a sam passwd.
**************************************************************/
+
void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
{
if (from == NULL || to == NULL)
@@ -669,19 +739,20 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
to->unknown_6 = from->unknown_6;
}
-
/*************************************************************
- copies a sam passwd.
+ Copies a SAM_ACCOUNT.
**************************************************************/
+
void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from)
{
- if (!from || !to) return;
+ if (!from || !to)
+ return;
memcpy(to, from, sizeof(SAM_ACCOUNT));
}
/*************************************************************
- change a password entry in the local smbpasswd file
+ Change a password entry in the local smbpasswd file.
FIXME!! The function needs to be abstracted into the
passdb interface or something. It is currently being called
@@ -723,8 +794,7 @@ account without a valid local system user.\n", user_name);
/* Get the smb passwd entry for this user */
pdb_init_sam(&sam_pass);
- if(!pdb_getsampwnam(sam_pass, user_name))
- {
+ if(!pdb_getsampwnam(sam_pass, user_name)) {
pdb_free_sam(sam_pass);
if(!(local_flags & LOCAL_ADD_USER)) {
@@ -780,25 +850,21 @@ account without a valid local system user.\n", user_name);
* and the valid last change time.
*/
- if(local_flags & LOCAL_DISABLE_USER)
+ if(local_flags & LOCAL_DISABLE_USER) {
pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED);
- else if (local_flags & LOCAL_ENABLE_USER)
- {
+ } else if (local_flags & LOCAL_ENABLE_USER) {
if(pdb_get_lanman_passwd(sam_pass) == NULL) {
pdb_set_lanman_passwd (sam_pass, new_p16);
pdb_set_nt_passwd (sam_pass, new_nt_p16);
}
pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED));
- }
- else if (local_flags & LOCAL_SET_NO_PASSWORD) {
+ } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ);
/* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
pdb_set_lanman_passwd (sam_pass, NULL);
pdb_set_nt_passwd (sam_pass, NULL);
- }
- else
- {
+ } else {
/*
* If we're dealing with setting a completely empty user account
* ie. One with a password of 'XXXX', but not set disabled (like
@@ -822,9 +888,7 @@ account without a valid local system user.\n", user_name);
return False;
}
slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
- }
- else
- {
+ } else {
if(!pdb_update_sam_account(sam_pass, True)) {
slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
pdb_free_sam(sam_pass);
@@ -842,10 +906,10 @@ account without a valid local system user.\n", user_name);
return True;
}
-
/*********************************************************************
- collection of get...() functions for SAM_ACCOUNT_INFO
+ Collection of get...() functions for SAM_ACCOUNT_INFO.
********************************************************************/
+
uint16 pdb_get_acct_ctrl (SAM_ACCOUNT *sampass)
{
if (sampass)
@@ -942,7 +1006,6 @@ uint8* pdb_get_lanman_passwd (SAM_ACCOUNT *sampass)
return (NULL);
}
-
uint32 pdb_get_user_rid (SAM_ACCOUNT *sampass)
{
if (sampass)
@@ -1088,15 +1151,15 @@ uint32 pdb_get_unknown6 (SAM_ACCOUNT *sampass)
}
/*********************************************************************
- collection of set...() functions for SAM_ACCOUNT_INFO
+ Collection of set...() functions for SAM_ACCOUNT_INFO.
********************************************************************/
+
BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags)
{
if (!sampass)
return False;
- if (sampass)
- {
+ if (sampass) {
sampass->acct_ctrl = flags;
return True;
}
@@ -1213,11 +1276,15 @@ BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid)
}
/*********************************************************************
- set the user's UNIX name
+ Set the user's UNIX name.
********************************************************************/
+
BOOL pdb_set_username(SAM_ACCOUNT *sampass, char *username)
{
- if (!sampass || !username)
+ if (!sampass)
+ return False;
+ *sampass->username = '\0';
+ if (!username)
return False;
StrnCpy (sampass->username, username, strlen(username));
@@ -1226,11 +1293,15 @@ BOOL pdb_set_username(SAM_ACCOUNT *sampass, char *username)
}
/*********************************************************************
- set the domain name
+ Set the domain name.
********************************************************************/
+
BOOL pdb_set_domain(SAM_ACCOUNT *sampass, char *domain)
{
- if (!sampass || !domain)
+ if (!sampass)
+ return False;
+ *sampass->domain = '\0';
+ if (!domain)
return False;
StrnCpy (sampass->domain, domain, strlen(domain));
@@ -1239,11 +1310,15 @@ BOOL pdb_set_domain(SAM_ACCOUNT *sampass, char *domain)
}
/*********************************************************************
- set the user's NT name
+ Set the user's NT name.
********************************************************************/
+
BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, char *nt_username)
{
- if (!sampass || !nt_username)
+ if (!sampass)
+ return False;
+ *sampass->nt_username = '\0';
+ if (!nt_username)
return False;
StrnCpy (sampass->nt_username, nt_username, strlen(nt_username));
@@ -1252,11 +1327,15 @@ BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, char *nt_username)
}
/*********************************************************************
- set the user's full name
+ Set the user's full name.
********************************************************************/
+
BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname)
{
- if (!sampass || !fullname)
+ if (!sampass)
+ return False;
+ *sampass->full_name = '\0';
+ if (!fullname)
return False;
StrnCpy (sampass->full_name, fullname, strlen(fullname));
@@ -1265,11 +1344,15 @@ BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname)
}
/*********************************************************************
- set the user's logon script
+ Set the user's logon script.
********************************************************************/
+
BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script)
{
- if (!sampass || !logon_script)
+ if (!sampass)
+ return False;
+ *sampass->logon_script = '\0';
+ if (!logon_script)
return False;
StrnCpy (sampass->logon_script, logon_script, strlen(logon_script));
@@ -1278,11 +1361,15 @@ BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script)
}
/*********************************************************************
- set the user's profile path
+ Set the user's profile path.
********************************************************************/
+
BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path)
{
- if (!sampass || !profile_path)
+ if (!sampass)
+ return False;
+ *sampass->profile_path = '\0';
+ if (!profile_path)
return False;
StrnCpy (sampass->profile_path, profile_path, strlen(profile_path));
@@ -1291,11 +1378,15 @@ BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path)
}
/*********************************************************************
- set the user's directory drive
+ Set the user's directory drive.
********************************************************************/
+
BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive)
{
- if (!sampass || !dir_drive)
+ if (!sampass)
+ return False;
+ *sampass->dir_drive = '\0';
+ if (!dir_drive)
return False;
StrnCpy (sampass->dir_drive, dir_drive, strlen(dir_drive));
@@ -1304,11 +1395,15 @@ BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive)
}
/*********************************************************************
- set the user's home directory
+ Set the user's home directory.
********************************************************************/
+
BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir)
{
- if (!sampass || !homedir)
+ if (!sampass)
+ return False;
+ *sampass->home_dir = '\0';
+ if (!homedir)
return False;
StrnCpy (sampass->home_dir, homedir, strlen(homedir));
@@ -1317,11 +1412,15 @@ BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir)
}
/*********************************************************************
- set the user's account description
+ Set the user's account description.
********************************************************************/
+
BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc)
{
- if (!sampass || !acct_desc)
+ if (!sampass)
+ return False;
+ *sampass->acct_desc = '\0';
+ if (!acct_desc)
return False;
StrnCpy (sampass->acct_desc, acct_desc, strlen(acct_desc));
@@ -1330,11 +1429,16 @@ BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc)
}
/*********************************************************************
- set the user's workstation allowed list
+ Set the user's workstation allowed list.
********************************************************************/
+
BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations)
{
- if (!sampass || !workstations) return False;
+ if (!sampass)
+ return False;
+ *sampass->workstations = '\0';
+ if (!workstations)
+ return False;
StrnCpy (sampass->workstations, workstations, strlen(workstations));
@@ -1342,11 +1446,16 @@ BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations)
}
/*********************************************************************
- set the user's dial string
+ Set the user's dial string.
********************************************************************/
+
BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial)
{
- if (!sampass || !munged_dial) return False;
+ if (!sampass)
+ return False;
+ *sampass->munged_dial = '\0';
+ if (!munged_dial)
+ return False;
StrnCpy (sampass->munged_dial, munged_dial, strlen(munged_dial));
@@ -1354,14 +1463,16 @@ BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial)
}
/*********************************************************************
- set the user's NT hash
+ Set the user's NT hash.
********************************************************************/
+
BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
{
- if (!sampass || !pwd) return False;
+ if (!sampass || !pwd)
+ return False;
if (sampass->nt_pw!=NULL)
- DEBUG(0,("pdb_set_nt_passwd: NT hash non NULL overwriting ?\n"));
+ DEBUG(4,("pdb_set_nt_passwd: NT hash non NULL overwritting ?\n"));
else
sampass->nt_pw=(unsigned char *)malloc(sizeof(unsigned char)*16);
@@ -1374,14 +1485,16 @@ BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
}
/*********************************************************************
- set the user's LM hash
+ Set the user's LM hash.
********************************************************************/
+
BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
{
- if (!sampass || !pwd) return False;
+ if (!sampass || !pwd)
+ return False;
if (sampass->lm_pw!=NULL)
- DEBUG(0,("pdb_set_lanman_passwd: LM hash non NULL overwriting ?\n"));
+ DEBUG(4,("pdb_set_lanman_passwd: LM hash non NULL overwritting ?\n"));
else
sampass->lm_pw=(unsigned char *)malloc(sizeof(unsigned char)*16);
@@ -1422,10 +1535,10 @@ BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn)
BOOL pdb_set_hours (SAM_ACCOUNT *sampass, uint8 *hours)
{
- if (!sampass) return False;
+ if (!sampass)
+ return False;
- if (!hours)
- {
+ if (!hours) {
memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
return True;
}
@@ -1434,4 +1547,3 @@ BOOL pdb_set_hours (SAM_ACCOUNT *sampass, uint8 *hours)
return True;
}
-
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
new file mode 100644
index 00000000000..f4ed014efe0
--- /dev/null
+++ b/source/passdb/pdb_ldap.c
@@ -0,0 +1,1014 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.9.
+ LDAP protocol helper functions for SAMBA
+ Copyright (C) Shahms King 2001
+ Copyright (C) Jean François Micouleau 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"
+
+#ifdef WITH_LDAP_SAM
+/* TODO:
+* persistent connections: if using NSS LDAP, many connections are made
+* however, using only one within Samba would be nice
+*
+* Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
+*
+* Other LDAP based login attributes: accountExpires, etc.
+* (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
+* structures don't have fields for some of these attributes)
+*
+* SSL is done, but can't get the certificate based authentication to work
+* against on my test platform (Linux 2.4, OpenLDAP 2.x)
+*/
+
+/* NOTE: this will NOT work against an Active Directory server
+* due to the fact that the two password fields cannot be retrieved
+* from a server; recommend using security = domain in this situation
+* and/or winbind
+*/
+
+#include <lber.h>
+#include <ldap.h>
+
+#ifndef SAM_ACCOUNT
+#define SAM_ACCOUNT struct sam_passwd
+#endif
+
+extern int DEBUGLEVEL;
+
+struct ldap_enum_info
+{
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+};
+
+static struct ldap_enum_info global_ldap_ent;
+
+
+/*******************************************************************
+ open a connection to the ldap server.
+******************************************************************/
+static BOOL
+ldap_open_connection (LDAP ** ldap_struct)
+{
+ int port;
+ int version, rc;
+ int tls = LDAP_OPT_X_TLS_HARD;
+
+ if (lp_ldap_ssl() == LDAP_SSL_ON && lp_ldap_port() == 389) {
+ port = 636;
+ }
+ else {
+ port = lp_ldap_port();
+ }
+
+ if ((*ldap_struct = ldap_init(lp_ldap_server(), port)) == NULL) {
+ DEBUG(0, ("The LDAP server is not responding !\n"));
+ return (False);
+ }
+
+ /* Connect to older servers using SSL and V2 rather than Start TLS */
+ if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
+ {
+ if (version != LDAP_VERSION2)
+ {
+ version = LDAP_VERSION2;
+ ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
+ }
+ }
+
+ switch (lp_ldap_ssl())
+ {
+ case LDAP_SSL_START_TLS:
+ if (ldap_get_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION,
+ &version) == LDAP_OPT_SUCCESS)
+ {
+ if (version < LDAP_VERSION3)
+ {
+ version = LDAP_VERSION3;
+ ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION,
+ &version);
+ }
+ }
+ if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
+ {
+ DEBUG(0,
+ ("Failed to issue the StartTLS instruction: %s\n",
+ ldap_err2string(rc)));
+ return False;
+ }
+ DEBUG (2, ("StartTLS issued: using a TLS connection\n"));
+ break;
+ case LDAP_SSL_ON:
+ if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
+ {
+ DEBUG(0, ("Failed to setup a TLS session\n"));
+ }
+ break;
+ case LDAP_SSL_OFF:
+ default:
+ }
+
+ DEBUG(2, ("ldap_open_connection: connection opened\n"));
+ return (True);
+}
+
+/*******************************************************************
+ connect to the ldap server under system privilege.
+******************************************************************/
+static BOOL ldap_connect_system(LDAP * ldap_struct)
+{
+ int rc;
+ static BOOL got_pw = False;
+ static pstring ldap_secret;
+
+ /* get the password if we don't have it already */
+ if (!got_pw && !(got_pw=fetch_ldap_pw(lp_ldap_admin_dn(), ldap_secret, sizeof(pstring))))
+ {
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password for %s from secrets.tdb\n",
+ lp_ldap_admin_dn()));
+ return False;
+ }
+
+ /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
+ (OpenLDAP) doesnt' seem to support it */
+ if ((rc = ldap_simple_bind_s(ldap_struct, lp_ldap_admin_dn(),
+ ldap_secret)) != LDAP_SUCCESS)
+ {
+ DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
+ return (False);
+ }
+
+ DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
+ return (True);
+}
+
+/*******************************************************************
+ run the search by name.
+******************************************************************/
+static int ldap_search_one_user (LDAP * ldap_struct, const char *filter, LDAPMessage ** result)
+{
+ int scope = LDAP_SCOPE_SUBTREE;
+ int rc;
+
+ DEBUG(2, ("ldap_search_one_user: searching for:[%s]\n", filter));
+
+ rc = ldap_search_s (ldap_struct, lp_ldap_suffix (), scope,
+ filter, NULL, 0, result);
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldap_search_one_user: Problem during the LDAP search: %s\n",
+ ldap_err2string (rc)));
+ DEBUG(3,("ldap_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
+ filter));
+ }
+ return (rc);
+}
+
+/*******************************************************************
+ run the search by name.
+******************************************************************/
+static int ldap_search_one_user_by_name (LDAP * ldap_struct, const char *user,
+ LDAPMessage ** result)
+{
+ pstring filter;
+
+ /*
+ in the filter expression, replace %u with the real name
+ so in ldap filter, %u MUST exist :-)
+ */
+ pstrcpy(filter, lp_ldap_filter());
+
+ /* have to use this here because $ is filtered out
+ * in pstring_sub
+ */
+ all_string_sub(filter, "%u", user, sizeof(pstring));
+
+ return ldap_search_one_user(ldap_struct, filter, result);
+}
+
+/*******************************************************************
+ run the search by uid.
+******************************************************************/
+static int ldap_search_one_user_by_uid(LDAP * ldap_struct, int uid,
+ LDAPMessage ** result)
+{
+ struct passwd *user;
+ pstring filter;
+
+ /* Get the username from the system and look that up in the LDAP */
+ user = sys_getpwuid(uid);
+ pstrcpy(filter, lp_ldap_filter());
+ all_string_sub(filter, "%u", user->pw_name, sizeof(pstring));
+
+ return ldap_search_one_user(ldap_struct, filter, result);
+}
+
+/*******************************************************************
+ run the search by rid.
+******************************************************************/
+static int ldap_search_one_user_by_rid (LDAP * ldap_struct, uint32 rid,
+ LDAPMessage ** result)
+{
+ pstring filter;
+ int rc;
+
+ /* check if the user rid exsists, if not, try searching on the uid */
+ snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
+ rc = ldap_search_one_user(ldap_struct, filter, result);
+
+ if (rc != LDAP_SUCCESS)
+ rc = ldap_search_one_user_by_uid(ldap_struct,
+ pdb_user_rid_to_uid(rid), result);
+
+ return rc;
+}
+
+/*******************************************************************
+search an attribute and return the first value found.
+******************************************************************/
+static void get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
+ char *attribute, char *value)
+{
+ char **valeurs;
+
+ if ((valeurs = ldap_get_values (ldap_struct, entry, attribute)) != NULL) {
+ pstrcpy(value, valeurs[0]);
+ ldap_value_free(valeurs);
+ DEBUG (2, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
+ }
+ else {
+ value = NULL;
+ DEBUG (2, ("get_single_attribute: [%s] = [NULL]\n", attribute));
+ }
+}
+
+/************************************************************************
+Routine to manage the LDAPMod structure array
+manage memory used by the array, by each struct, and values
+
+************************************************************************/
+static void make_a_mod (LDAPMod *** modlist, int modop, char *attribute, char *value)
+{
+ LDAPMod **mods;
+ int i;
+ int j;
+
+ mods = *modlist;
+
+ if (attribute == NULL || *attribute == '\0')
+ return;
+
+ if (value == NULL || *value == '\0')
+ return;
+
+ if (mods == NULL)
+ {
+ mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
+ if (mods == NULL)
+ {
+ DEBUG(0, ("make_a_mod: out of memory!\n"));
+ return;
+ }
+ mods[0] = NULL;
+ }
+
+ for (i = 0; mods[i] != NULL; ++i) {
+ if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
+ break;
+ }
+
+ if (mods[i] == NULL)
+ {
+ mods = (LDAPMod **) realloc (mods, (i + 2) * sizeof (LDAPMod *));
+ if (mods == NULL)
+ {
+ DEBUG(0, ("make_a_mod: out of memory!\n"));
+ return;
+ }
+ mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
+ if (mods[i] == NULL)
+ {
+ DEBUG(0, ("make_a_mod: out of memory!\n"));
+ return;
+ }
+ mods[i]->mod_op = modop;
+ mods[i]->mod_values = NULL;
+ mods[i]->mod_type = strdup(attribute);
+ mods[i + 1] = NULL;
+ }
+
+ if (value != NULL)
+ {
+ j = 0;
+ if (mods[i]->mod_values != NULL) {
+ for (; mods[i]->mod_values[j] != NULL; j++);
+ }
+ mods[i]->mod_values = (char **)realloc(mods[i]->mod_values,
+ (j + 2) * sizeof (char *));
+
+ if (mods[i]->mod_values == NULL) {
+ DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
+ return;
+ }
+ mods[i]->mod_values[j] = strdup(value);
+ mods[i]->mod_values[j + 1] = NULL;
+ }
+ *modlist = mods;
+}
+
+/* New Interface is being implemented here */
+
+/**********************************************************************
+Initialize SAM_ACCOUNT from an LDAP query
+(Based on init_sam_from_buffer in pdb_tdb.c)
+*********************************************************************/
+static BOOL init_sam_from_ldap (SAM_ACCOUNT * sampass,
+ LDAP * ldap_struct, LDAPMessage * entry)
+{
+ time_t logon_time,
+ logoff_time,
+ kickoff_time,
+ pass_last_set_time,
+ pass_can_change_time,
+ pass_must_change_time;
+ static pstring username;
+ static pstring domain;
+ static pstring nt_username;
+ static pstring fullname;
+ static pstring homedir;
+ static pstring dir_drive;
+ static pstring logon_script;
+ static pstring profile_path;
+ static pstring acct_desc;
+ static pstring munged_dial;
+ static pstring workstations;
+ struct passwd *sys_user;
+ uint32 user_rid, group_rid;
+ static uint8 smblmpwd[16];
+ static uint8 smbntpwd[16];
+ uint16 acct_ctrl, logon_divs;
+ uint32 hours_len;
+ uint8 *hours;
+ pstring temp;
+
+ get_single_attribute(ldap_struct, entry, "uid", username);
+ DEBUG(2, ("Entry found for user: %s\n", username));
+
+ /* not sure about this for nt_username */
+ get_single_attribute (ldap_struct, entry, "sAMAccountName", nt_username);
+ if (!nt_username)
+ pstrcpy(nt_username, username);
+
+ get_single_attribute(ldap_struct, entry, "sambaDomain", domain);
+ if (!domain)
+ pstrcpy(domain, lp_workgroup());
+
+ get_single_attribute(ldap_struct, entry, "pwdLastSet", temp);
+ pass_last_set_time = (time_t) strtol(temp, NULL, 16);
+
+ get_single_attribute(ldap_struct, entry, "logonTime", temp);
+ logon_time = (time_t) strtol(temp, NULL, 16);
+
+ get_single_attribute(ldap_struct, entry, "logoffTime", temp);
+ logoff_time = (time_t) strtol(temp, NULL, 16);
+
+ get_single_attribute(ldap_struct, entry, "kickoffTime", temp);
+ kickoff_time = (time_t) strtol(temp, NULL, 16);
+
+ get_single_attribute(ldap_struct, entry, "pwdCanChange", temp);
+ pass_can_change_time = (time_t) strtol(temp, NULL, 16);
+
+ get_single_attribute(ldap_struct, entry, "pwdMustChange", temp);
+ pass_must_change_time = (time_t) strtol(temp, NULL, 16);
+
+ /* recommend that 'gecos' and 'displayName' should refer to the same
+ * attribute OID. userFullName depreciated, only used by Samba
+ * primary rules of LDAP: don't make a new attribute when one is already defined
+ * that fits your needs; using gecos then displayName then cn rather than 'userFullName'
+ */
+
+ get_single_attribute(ldap_struct, entry, "gecos", fullname);
+
+ if (!fullname) {
+ get_single_attribute(ldap_struct, entry, "displayName", fullname);
+ get_single_attribute(ldap_struct, entry, "cn", fullname);
+ }
+
+ get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive);
+ get_single_attribute(ldap_struct, entry, "scriptPath", logon_script);
+ get_single_attribute(ldap_struct, entry, "profilePath", profile_path);
+ get_single_attribute(ldap_struct, entry, "description", acct_desc);
+ get_single_attribute (ldap_struct, entry, "userWorkstations", workstations);
+
+ get_single_attribute(ldap_struct, entry, "rid", temp);
+ user_rid = (uint32)strtol(temp, NULL, 16);
+ get_single_attribute(ldap_struct, entry, "primaryGroupID", temp);
+ group_rid = (uint32)strtol(temp, NULL, 16);
+
+
+ /* These values MAY be in LDAP, but they can also be retrieved through
+ * sys_getpw*() which is how we're doing it (if you use nss_ldap, then
+ * these values will be stored in LDAP as well, but if not, we want the
+ * local values to override the LDAP for this anyway
+ * homeDirectory attribute
+ */
+ sys_user = sys_getpwnam(username);
+ if (sys_user == NULL)
+ return False;
+ pstrcpy(homedir, sys_user->pw_dir);
+
+
+ /* FIXME: hours stuff should be cleaner */
+ logon_divs = 168;
+ hours_len = 21;
+ hours = malloc(sizeof(hours) * hours_len);
+ memset(hours, 0xff, hours_len);
+
+ get_single_attribute (ldap_struct, entry, "lmPassword", temp);
+ pdb_gethexpwd(temp, smblmpwd);
+ memset((char *)temp, '\0', sizeof(temp));
+ get_single_attribute (ldap_struct, entry, "ntPassword", temp);
+ pdb_gethexpwd(temp, smbntpwd);
+ memset((char *)temp, '\0', sizeof(temp));
+ get_single_attribute (ldap_struct, entry, "acctFlags", temp);
+ acct_ctrl = pdb_decode_acct_ctrl(temp);
+
+ if (acct_ctrl == 0)
+ acct_ctrl |= ACB_NORMAL;
+
+
+ pdb_set_acct_ctrl(sampass, acct_ctrl);
+ pdb_set_logon_time(sampass, logon_time);
+ pdb_set_logoff_time(sampass, logoff_time);
+ pdb_set_kickoff_time(sampass, kickoff_time);
+ pdb_set_pass_can_change_time(sampass, pass_can_change_time);
+ pdb_set_pass_must_change_time(sampass, pass_must_change_time);
+ pdb_set_pass_last_set_time(sampass, pass_last_set_time);
+
+ pdb_set_hours_len(sampass, hours_len);
+ pdb_set_logons_divs(sampass, logon_divs);
+
+ pdb_set_uid(sampass, sys_user->pw_uid);
+ pdb_set_gid(sampass, sys_user->pw_gid);
+ pdb_set_user_rid(sampass, user_rid);
+ pdb_set_group_rid(sampass, group_rid);
+
+ pdb_set_username(sampass, username);
+
+ pdb_set_domain(sampass, domain);
+ pdb_set_nt_username(sampass, nt_username);
+
+ pdb_set_fullname(sampass, fullname);
+
+ pdb_set_logon_script(sampass, logon_script);
+ pdb_set_profile_path(sampass, profile_path);
+ pdb_set_dir_drive(sampass, dir_drive);
+ pdb_set_homedir(sampass, homedir);
+ pdb_set_acct_desc(sampass, acct_desc);
+ pdb_set_workstations(sampass, workstations);
+ pdb_set_munged_dial(sampass, munged_dial);
+ pdb_set_nt_passwd(sampass, smbntpwd);
+ pdb_set_lanman_passwd(sampass, smblmpwd);
+
+ /* pdb_set_unknown_3(sampass, unknown3); */
+ /* pdb_set_unknown_5(sampass, unknown5); */
+ /* pdb_set_unknown_6(sampass, unknown6); */
+
+ pdb_set_hours(sampass, hours);
+
+ return True;
+}
+
+/**********************************************************************
+Initialize SAM_ACCOUNT from an LDAP query
+(Based on init_buffer_from_sam in pdb_tdb.c)
+*********************************************************************/
+static BOOL init_ldap_from_sam (LDAPMod *** mods, int ldap_state, SAM_ACCOUNT * sampass)
+{
+ pstring temp;
+
+ *mods = NULL;
+
+ /*
+ * took out adding "objectclass: sambaAccount"
+ * do this on a per-mod basis
+ */
+
+
+ make_a_mod(mods, ldap_state, "uid", pdb_get_username(sampass));
+ DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
+
+ /* not sure about using this for the nt_username */
+ make_a_mod (mods, ldap_state, "sAMAccountName", pdb_get_nt_username(sampass));
+ make_a_mod(mods, ldap_state, "sambaDomain", pdb_get_domain(sampass));
+
+ slprintf(temp, sizeof(temp) - 1, "%i", pdb_get_uid(sampass));
+ make_a_mod(mods, ldap_state, "uidNumber", temp);
+
+ slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
+ make_a_mod(mods, ldap_state, "pwdLastSet", temp);
+
+ slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
+ make_a_mod(mods, ldap_state, "logonTime", temp);
+
+ slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
+ make_a_mod(mods, ldap_state, "logoffTime", temp);
+
+ slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
+ make_a_mod(mods, ldap_state, "kickoffTime", temp);
+
+ slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
+ make_a_mod(mods, ldap_state, "pwdCanChange", temp);
+
+ slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
+ make_a_mod(mods, ldap_state, "pwdMustChange", temp);
+
+ /* displayName, cn, and gecos should all be the same
+ * most easily accomplished by giving them the same OID
+ * gecos isn't set here b/c it should be handled by the
+ * add-user script
+ */
+
+ make_a_mod(mods, ldap_state, "displayName", pdb_get_fullname(sampass));
+ make_a_mod(mods, ldap_state, "cn", pdb_get_fullname(sampass));
+
+ make_a_mod(mods, ldap_state, "homeDirectory", pdb_get_homedir(sampass));
+ make_a_mod(mods, ldap_state, "homeDrive", pdb_get_dirdrive(sampass));
+ make_a_mod(mods, ldap_state, "scriptPath", pdb_get_logon_script(sampass));
+ make_a_mod(mods, ldap_state, "profilePath", pdb_get_profile_path(sampass));
+ make_a_mod(mods, ldap_state, "description", pdb_get_acct_desc(sampass));
+ make_a_mod(mods, ldap_state, "userWorkstations", pdb_get_workstations(sampass));
+
+ slprintf(temp, sizeof(temp) - 1, "%i", sampass->user_rid);
+ make_a_mod(mods, ldap_state, "rid", temp);
+
+ slprintf(temp, sizeof(temp) - 1, "%i", sampass->group_rid);
+ make_a_mod(mods, ldap_state, "primaryGroupID", temp);
+
+ /* FIXME: Hours stuff goes in LDAP */
+ pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass));
+ make_a_mod (mods, ldap_state, "lmPassword", temp);
+ pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass));
+ make_a_mod (mods, ldap_state, "ntPassword", temp);
+ make_a_mod (mods, ldap_state, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
+ NEW_PW_FORMAT_SPACE_PADDED_LEN));
+
+ return True;
+}
+
+/**********************************************************************
+Connect to LDAP server for password enumeration
+*********************************************************************/
+BOOL pdb_setsampwent(BOOL update)
+{
+ int rc;
+ pstring filter;
+
+ if (!ldap_open_connection(&global_ldap_ent.ldap_struct))
+ {
+ return False;
+ }
+ if (!ldap_connect_system(global_ldap_ent.ldap_struct))
+ {
+ ldap_unbind(global_ldap_ent.ldap_struct);
+ return False;
+ }
+
+ pstrcpy(filter, lp_ldap_filter());
+ all_string_sub(filter, "%u", "*", sizeof(pstring));
+
+ rc = ldap_search_s(global_ldap_ent.ldap_struct, lp_ldap_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, NULL, 0,
+ &global_ldap_ent.result);
+
+ if (rc != LDAP_SUCCESS)
+ {
+ DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
+ DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
+ ldap_msgfree(global_ldap_ent.result);
+ ldap_unbind(global_ldap_ent.ldap_struct);
+ global_ldap_ent.ldap_struct = NULL;
+ global_ldap_ent.result = NULL;
+ return False;
+ }
+
+ DEBUG(2, ("pdb_setsampwent: %d entries in the base!\n",
+ ldap_count_entries(global_ldap_ent.ldap_struct,
+ global_ldap_ent.result)));
+
+ global_ldap_ent.entry = ldap_first_entry(global_ldap_ent.ldap_struct,
+ global_ldap_ent.result);
+
+ return True;
+}
+
+/**********************************************************************
+End enumeration of the LDAP password list
+*********************************************************************/
+void pdb_endsampwent(void)
+{
+ if (global_ldap_ent.ldap_struct && global_ldap_ent.result)
+ {
+ ldap_msgfree(global_ldap_ent.result);
+ ldap_unbind(global_ldap_ent.ldap_struct);
+ global_ldap_ent.ldap_struct = NULL;
+ global_ldap_ent.result = NULL;
+ }
+}
+
+/**********************************************************************
+Get the next entry in the LDAP password database
+*********************************************************************/
+BOOL pdb_getsampwent(SAM_ACCOUNT * user)
+{
+ if (!global_ldap_ent.entry)
+ return False;
+
+ global_ldap_ent.entry = ldap_next_entry(global_ldap_ent.ldap_struct,
+ global_ldap_ent.entry);
+
+ if (global_ldap_ent.entry != NULL)
+ {
+ return init_sam_from_ldap(user, global_ldap_ent.ldap_struct,
+ global_ldap_ent.entry);
+ }
+ return False;
+}
+
+/**********************************************************************
+Get SAM_ACCOUNT entry from LDAP by username
+*********************************************************************/
+BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname)
+{
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+
+ if (!ldap_open_connection(&ldap_struct))
+ return False;
+ if (!ldap_connect_system(ldap_struct))
+ {
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+ if (ldap_search_one_user_by_name(ldap_struct, sname, &result) !=
+ LDAP_SUCCESS)
+ {
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+ if (ldap_count_entries(ldap_struct, result) < 1)
+ {
+ DEBUG(0,
+ ("We don't find this user [%s] count=%d\n", sname,
+ ldap_count_entries(ldap_struct, result)));
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+ entry = ldap_first_entry(ldap_struct, result);
+ if (entry)
+ {
+ init_sam_from_ldap(user, ldap_struct, entry);
+ ldap_msgfree(result);
+ ldap_unbind(ldap_struct);
+ return True;
+ }
+ else
+ {
+ ldap_msgfree(result);
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+}
+
+/**********************************************************************
+Get SAM_ACCOUNT entry from LDAP by rid
+*********************************************************************/
+BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
+{
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+
+ if (!ldap_open_connection(&ldap_struct))
+ return False;
+
+ if (!ldap_connect_system(ldap_struct))
+ {
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+ if (ldap_search_one_user_by_rid(ldap_struct, rid, &result) !=
+ LDAP_SUCCESS)
+ {
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+
+ if (ldap_count_entries(ldap_struct, result) < 1)
+ {
+ DEBUG(0,
+ ("We don't find this rid [%i] count=%d\n", rid,
+ ldap_count_entries(ldap_struct, result)));
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+
+ entry = ldap_first_entry(ldap_struct, result);
+ if (entry)
+ {
+ init_sam_from_ldap(user, ldap_struct, entry);
+ ldap_msgfree(result);
+ ldap_unbind(ldap_struct);
+ return True;
+ }
+ else
+ {
+ ldap_msgfree(result);
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+}
+
+/**********************************************************************
+ Get SAM_ACCOUNT entry from LDAP by uid
+*********************************************************************/
+BOOL pdb_getsampwuid(SAM_ACCOUNT * user, uid_t uid)
+{
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+
+ if (!ldap_open_connection(&ldap_struct))
+ return False;
+
+ if (!ldap_connect_system(ldap_struct))
+ {
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+ if (ldap_search_one_user_by_uid(ldap_struct, uid, &result) !=
+ LDAP_SUCCESS)
+ {
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+
+ if (ldap_count_entries(ldap_struct, result) < 1)
+ {
+ DEBUG(0,
+ ("We don't find this uid [%i] count=%d\n", uid,
+ ldap_count_entries(ldap_struct, result)));
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+ entry = ldap_first_entry(ldap_struct, result);
+ if (entry)
+ {
+ init_sam_from_ldap(user, ldap_struct, entry);
+ ldap_msgfree(result);
+ ldap_unbind(ldap_struct);
+ return True;
+ }
+ else
+ {
+ ldap_msgfree(result);
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+}
+
+
+/**********************************************************************
+Delete entry from LDAP for username
+*********************************************************************/
+BOOL pdb_delete_sam_account(char *sname)
+{
+ int rc;
+ char *dn;
+ LDAP *ldap_struct;
+ LDAPMessage *entry;
+ LDAPMessage *result;
+
+ if (!ldap_open_connection (&ldap_struct))
+ return False;
+
+ DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
+
+ if (!ldap_connect_system (ldap_struct)) {
+ ldap_unbind (ldap_struct);
+ DEBUG(0, ("Failed to delete user %s from LDAP.\n", sname));
+ return False;
+ }
+
+ rc = ldap_search_one_user_by_name (ldap_struct, sname, &result);
+ if (ldap_count_entries (ldap_struct, result) == 0) {
+ DEBUG (0, ("User doesn't exit!\n"));
+ ldap_msgfree (result);
+ ldap_unbind (ldap_struct);
+ return False;
+ }
+
+ entry = ldap_first_entry (ldap_struct, result);
+ dn = ldap_get_dn (ldap_struct, entry);
+
+ rc = ldap_delete_s (ldap_struct, dn);
+
+ ldap_memfree (dn);
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error;
+ ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n",
+ sname, ldap_err2string (rc), ld_error));
+ free (ld_error);
+ ldap_unbind (ldap_struct);
+ return False;
+ }
+
+ DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname));
+ ldap_unbind (ldap_struct);
+ return True;
+}
+
+/**********************************************************************
+Update SAM_ACCOUNT
+*********************************************************************/
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
+{
+ int rc;
+ char *dn;
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+ LDAPMod **mods;
+
+ if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
+ return False;
+
+ if (!ldap_connect_system(ldap_struct)) /* connect as system account */
+ {
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+
+ rc = ldap_search_one_user_by_name(ldap_struct,
+ pdb_get_username(newpwd), &result);
+
+ if (ldap_count_entries(ldap_struct, result) == 0)
+ {
+ DEBUG(0, ("No user to modify!\n"));
+ ldap_msgfree(result);
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+
+ init_ldap_from_sam(&mods, LDAP_MOD_REPLACE, newpwd);
+
+ entry = ldap_first_entry(ldap_struct, result);
+ dn = ldap_get_dn(ldap_struct, entry);
+
+ rc = ldap_modify_s(ldap_struct, dn, mods);
+
+ if (rc != LDAP_SUCCESS)
+ {
+ char *ld_error;
+ ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING,
+ &ld_error);
+ DEBUG(0,
+ ("failed to modify user with uid = %s with: %s\n\t%s\n",
+ pdb_get_username(newpwd), ldap_err2string(rc),
+ ld_error));
+ free(ld_error);
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+
+ DEBUG(2,
+ ("successfully modified uid = %s in the LDAP database\n",
+ pdb_get_username(newpwd)));
+ ldap_mods_free(mods, 1);
+ ldap_unbind(ldap_struct);
+ return True;
+}
+
+/**********************************************************************
+Add SAM_ACCOUNT to LDAP
+*********************************************************************/
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
+{
+ int rc;
+ pstring filter;
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ pstring dn;
+ LDAPMod **mods;
+ int ldap_op = LDAP_MOD_ADD;
+
+ if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
+ {
+ return False;
+ }
+
+ if (!ldap_connect_system(ldap_struct)) /* connect as system account */
+ {
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+
+ if (pdb_get_username(newpwd) != NULL) {
+ slprintf (dn, sizeof (dn) - 1, "uid=%s,%s",
+ pdb_get_username(newpwd), lp_ldap_suffix ());
+ }
+ else
+ {
+ return False;
+ }
+
+
+ rc = ldap_search_one_user_by_name (ldap_struct, pdb_get_username(newpwd), &result);
+
+ if (ldap_count_entries(ldap_struct, result) != 0)
+ {
+ DEBUG(0,("User already in the base, with samba properties\n"));
+ ldap_msgfree(result);
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+ ldap_msgfree(result);
+
+ slprintf (filter, sizeof (filter) - 1, "uid=%s", pdb_get_username(newpwd));
+ rc = ldap_search_one_user(ldap_struct, filter, &result);
+ if (ldap_count_entries(ldap_struct, result) == 1)
+ {
+ char *tmp;
+ LDAPMessage *entry;
+ DEBUG(3,("User exists without samba properties: adding them\n"));
+ ldap_op = LDAP_MOD_REPLACE;
+ entry = ldap_first_entry (ldap_struct, result);
+ tmp = ldap_get_dn (ldap_struct, entry);
+ slprintf (dn, sizeof (dn) - 1, "%s", tmp);
+ ldap_memfree (tmp);
+ }
+ else
+ {
+ DEBUG (3, ("More than one user with that uid exists: bailing out!\n"));
+ return False;
+ }
+
+ ldap_msgfree(result);
+
+ init_ldap_from_sam(&mods, ldap_op, newpwd);
+ make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
+
+ if (ldap_op == LDAP_MOD_REPLACE) {
+ rc = ldap_modify_s(ldap_struct, dn, mods);
+ }
+ else {
+ rc = ldap_add_s(ldap_struct, dn, mods);
+ }
+
+ if (rc != LDAP_SUCCESS)
+ {
+ char *ld_error;
+
+ ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(0,("failed to modify user with uid = %s with: %s\n\t%s\n",
+ pdb_get_username(newpwd), ldap_err2string (rc), ld_error));
+ free(ld_error);
+ ldap_mods_free(mods, 1);
+ ldap_unbind(ldap_struct);
+ return False;
+ }
+
+ DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
+ ldap_mods_free(mods, 1);
+ ldap_unbind(ldap_struct);
+ return True;
+}
+
+#else
+void dummy_function(void);
+void
+dummy_function (void)
+{
+} /* stop some compilers complaining */
+#endif
diff --git a/source/passdb/pdb_nisplus.c b/source/passdb/pdb_nisplus.c
new file mode 100644
index 00000000000..368fb3dc49d
--- /dev/null
+++ b/source/passdb/pdb_nisplus.c
@@ -0,0 +1,1401 @@
+/*
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ * Copyright (C) Benny Holmgren 1998 <bigfoot@astrakan.hgs.se>
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998.
+ * Copyright (C) Toomas Soomea <tsoome@ut.ee> 2001
+ *
+ * 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"
+
+#ifdef WITH_NISPLUS_SAM
+
+#ifdef BROKEN_NISPLUS_INCLUDE_FILES
+
+/*
+ * The following lines are needed due to buggy include files
+ * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
+ * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
+ * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
+ * an enum in /usr/include/rpcsvc/nis.h.
+ */
+
+#if defined(GROUP)
+#undef GROUP
+#endif
+
+#if defined(GROUP_OBJ)
+#undef GROUP_OBJ
+#endif
+
+#endif
+
+#include <rpcsvc/nis.h>
+
+extern int DEBUGLEVEL;
+extern pstring samlogon_user;
+extern BOOL sam_logon_in_ssb;
+
+struct nisp_enum_info
+{
+ nis_result *result;
+ int enum_entry;
+};
+
+static struct nisp_enum_info global_nisp_ent;
+static VOLATILE sig_atomic_t gotalarm;
+
+/***************************************************************
+
+ the fields for the NIS+ table, generated from mknissmbpwtbl.sh, are:
+
+ name=S,nogw=r
+ uid=S,nogw=r
+ user_rid=S,nogw=r
+ smb_grpid=,nw+r
+ group_rid=,nw+r
+ acb=,nw+r
+
+ lmpwd=C,nw=,g=r,o=rm
+ ntpwd=C,nw=,g=r,o=rm
+
+ logon_t=,nw+r
+ logoff_t=,nw+r
+ kick_t=,nw+r
+ pwdlset_t=,nw+r
+ pwdlchg_t=,nw+r
+ pwdmchg_t=,nw+r
+
+ full_name=,nw+r
+ home_dir=,nw+r
+ dir_drive=,nw+r
+ logon_script=,nw+r
+ profile_path=,nw+r
+ acct_desc=,nw+r
+ workstations=,nw+r
+
+ hours=,nw+r
+
+****************************************************************/
+
+#define NPF_NAME 0
+#define NPF_UID 1
+#define NPF_USER_RID 2
+#define NPF_SMB_GRPID 3
+#define NPF_GROUP_RID 4
+#define NPF_ACB 5
+#define NPF_LMPWD 6
+#define NPF_NTPWD 7
+#define NPF_LOGON_T 8
+#define NPF_LOGOFF_T 9
+#define NPF_KICK_T 10
+#define NPF_PWDLSET_T 11
+#define NPF_PWDCCHG_T 12
+#define NPF_PWDMCHG_T 13
+#define NPF_FULL_NAME 14
+#define NPF_HOME_DIR 15
+#define NPF_DIR_DRIVE 16
+#define NPF_LOGON_SCRIPT 17
+#define NPF_PROFILE_PATH 18
+#define NPF_ACCT_DESC 19
+#define NPF_WORKSTATIONS 20
+#define NPF_HOURS 21
+
+/***************************************************************
+ Signal function to tell us we timed out.
+****************************************************************/
+static void gotalarm_sig(void)
+{
+ gotalarm = 1;
+}
+
+/***************************************************************
+ make_nisname_from_user_rid
+ ****************************************************************/
+static char *make_nisname_from_user_rid(uint32 rid, char *pfile)
+{
+ static pstring nisname;
+
+ safe_strcpy(nisname, "[user_rid=", sizeof(nisname)-1);
+ slprintf(nisname, sizeof(nisname)-1, "%s%d", nisname, rid);
+ safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1);
+ safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1);
+
+ return nisname;
+}
+
+/***************************************************************
+ make_nisname_from_uid
+ ****************************************************************/
+static char *make_nisname_from_uid(int uid, char *pfile)
+{
+ static pstring nisname;
+
+ safe_strcpy(nisname, "[uid=", sizeof(nisname)-1);
+ slprintf(nisname, sizeof(nisname)-1, "%s%d", nisname, uid);
+ safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1);
+ safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1);
+
+ return nisname;
+}
+
+/***************************************************************
+ make_nisname_from_name
+ ****************************************************************/
+static char *make_nisname_from_name(char *user_name, char *pfile)
+{
+ static pstring nisname;
+
+ safe_strcpy(nisname, "[name=", sizeof(nisname)-1);
+ safe_strcat(nisname, user_name, sizeof(nisname) - strlen(nisname) - 1);
+ safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1);
+ safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1);
+
+ return nisname;
+}
+
+/*************************************************************************
+ gets a NIS+ attribute
+ *************************************************************************/
+static void get_single_attribute(nis_object *new_obj, int col,
+ char *val, int len)
+{
+ int entry_len;
+
+ if (new_obj == NULL || val == NULL) return;
+
+ entry_len = ENTRY_LEN(new_obj, col);
+ if (len > entry_len)
+ {
+ len = entry_len;
+ }
+
+ safe_strcpy(val, ENTRY_VAL(new_obj, col), len-1);
+}
+
+/************************************************************************
+ makes a struct sam_passwd from a NIS+ object.
+ ************************************************************************/
+static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, nis_object *obj)
+{
+ char *ptr;
+ pstring full_name; /* this must be translated to dos code page */
+ pstring acct_desc; /* this must be translated to dos code page */
+ pstring home_dir; /* set default value from smb.conf for user */
+ pstring home_drive; /* set default value from smb.conf for user */
+ pstring logon_script; /* set default value from smb.conf for user */
+ pstring profile_path; /* set default value from smb.conf for user */
+ pstring hours;
+ int hours_len;
+ unsigned char smbpwd[16];
+ unsigned char smbntpwd[16];
+
+
+ /*
+ * time values. note: this code assumes 32bit time_t!
+ */
+
+ pdb_set_logon_time(pw_buf, -1);
+ ptr = (uchar *)ENTRY_VAL(obj, NPF_LOGON_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "LNT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_logon_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ pdb_set_logoff_time(pw_buf, -1);
+ ptr = (uchar *)ENTRY_VAL(obj, NPF_LOGOFF_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "LOT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_logoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ pdb_set_kickoff_time(pw_buf, -1);
+ ptr = (uchar *)ENTRY_VAL(obj, NPF_KICK_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "KOT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_kickoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ pdb_set_pass_last_set_time(pw_buf, -1);
+ ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDLSET_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "LCT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_pass_last_set_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ pdb_set_pass_can_change_time(pw_buf, -1);
+ ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDCCHG_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "CCT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_pass_can_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ pdb_set_pass_must_change_time(pw_buf, -1);
+ ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDMCHG_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "MCT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_pass_must_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ /* string values */
+ pdb_set_username(pw_buf, ENTRY_VAL(obj, NPF_NAME));
+ pdb_set_domain(pw_buf, lp_workgroup());
+ /* pdb_set_nt_username() -- cant set it here... */
+
+ get_single_attribute(obj, NPF_FULL_NAME, full_name, sizeof(pstring));
+ unix_to_dos(full_name, True);
+ pdb_set_fullname(pw_buf, full_name);
+
+ pdb_set_acct_ctrl(pw_buf, pdb_decode_acct_ctrl(ENTRY_VAL(obj,
+ NPF_ACB)));
+
+ get_single_attribute(obj, NPF_ACCT_DESC, acct_desc, sizeof(pstring));
+ unix_to_dos(acct_desc, True);
+ pdb_set_acct_desc(pw_buf, acct_desc);
+
+ pdb_set_workstations(pw_buf, ENTRY_VAL(obj, NPF_WORKSTATIONS));
+ pdb_set_munged_dial(pw_buf, NULL);
+
+ pdb_set_uid(pw_buf, atoi(ENTRY_VAL(obj, NPF_UID)));
+ pdb_set_gid(pw_buf, atoi(ENTRY_VAL(obj, NPF_SMB_GRPID)));
+ pdb_set_user_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_USER_RID)));
+ pdb_set_group_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_GROUP_RID)));
+
+ /* values, must exist for user */
+ if( !(pdb_get_acct_ctrl(pw_buf) & ACB_WSTRUST) ) {
+ /* FIXME!! This doesn't belong here.
+ Should be set in net_sam_logon()
+ --jerry */
+ pstrcpy(samlogon_user, pdb_get_username(pw_buf));
+
+ get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring));
+ if( !(home_dir && *home_dir) )
+ pstrcpy(home_dir, lp_logon_home());
+ pdb_set_homedir(pw_buf, home_dir);
+
+ get_single_attribute(obj, NPF_DIR_DRIVE, home_drive, sizeof(pstring));
+ if( !(home_drive && *home_drive) )
+ pstrcpy(home_drive, lp_logon_drive());
+ pdb_set_dir_drive(pw_buf, home_drive);
+
+ get_single_attribute(obj, NPF_LOGON_SCRIPT, logon_script,
+ sizeof(pstring));
+ if( !(logon_script && *logon_script) )
+ pstrcpy(logon_script, lp_logon_script());
+ pdb_set_logon_script(pw_buf, logon_script);
+
+ get_single_attribute(obj, NPF_PROFILE_PATH, profile_path,
+ sizeof(pstring));
+ if( !(profile_path && *profile_path) )
+ pstrcpy(profile_path, lp_logon_path());
+ pdb_set_profile_path(pw_buf, profile_path);
+ } else {
+ /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
+ pdb_set_group_rid (pw_buf, DOMAIN_GROUP_RID_USERS);
+ }
+
+ /* Check the lanman password column. */
+ ptr = (char *)ENTRY_VAL(obj, NPF_LMPWD);
+ pdb_set_lanman_passwd(pw_buf, NULL);
+
+ if (!strncasecmp(ptr, "NO PASSWORD", 11)) {
+ pdb_set_acct_ctrl(pw_buf, pdb_get_acct_ctrl(pw_buf) | ACB_PWNOTREQ);
+ } else {
+ if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbpwd)) {
+ DEBUG(0, ("malformed LM pwd entry: %s.\n",
+ pdb_get_username(pw_buf)));
+ return False;
+ }
+ pdb_set_lanman_passwd(pw_buf, smbpwd);
+ }
+
+ /* Check the NT password column. */
+ ptr = ENTRY_VAL(obj, NPF_NTPWD);
+ pdb_set_nt_passwd(pw_buf, NULL);
+
+ if (!(pdb_get_acct_ctrl(pw_buf) & ACB_PWNOTREQ) &&
+ strncasecmp(ptr, "NO PASSWORD", 11)) {
+ if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbntpwd)) {
+ DEBUG(0, ("malformed NT pwd entry:
+ uid = %d.\n",
+ pdb_get_uid(pw_buf)));
+ return False;
+ }
+ pdb_set_nt_passwd(pw_buf, smbntpwd);
+ }
+
+ pdb_set_unknown_3(pw_buf, 0xffffff); /* don't know */
+ pdb_set_logons_divs(pw_buf, 168); /* hours per week */
+
+ if( (hours_len = ENTRY_LEN(obj, NPF_HOURS)) == 21 ) {
+ memcpy(hours, ENTRY_VAL(obj, NPF_HOURS), hours_len);
+ } else {
+ hours_len = 21; /* 21 times 8 bits = 168 */
+ /* available at all hours */
+ memset(hours, 0xff, hours_len);
+ }
+ pdb_set_hours_len(pw_buf, hours_len);
+ pdb_set_hours(pw_buf, hours);
+
+ pdb_set_unknown_5(pw_buf, 0x00020000); /* don't know */
+ pdb_set_unknown_6(pw_buf, 0x000004ec); /* don't know */
+
+ return True;
+}
+
+/************************************************************************
+ makes a struct sam_passwd from a NIS+ result.
+ ************************************************************************/
+static BOOL make_sam_from_nisresult(SAM_ACCOUNT *pw_buf, nis_result *result)
+{
+ if (pw_buf == NULL || result == NULL) return False;
+
+ if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND)
+ {
+ DEBUG(0, ("NIS+ lookup failure: %s\n",
+ nis_sperrno(result->status)));
+ return False;
+ }
+
+ /* User not found. */
+ if (NIS_RES_NUMOBJ(result) <= 0)
+ {
+ DEBUG(10, ("user not found in NIS+\n"));
+ return False;
+ }
+
+ if (NIS_RES_NUMOBJ(result) > 1)
+ {
+ DEBUG(10, ("WARNING: Multiple entries for user in NIS+ table!\n"));
+ }
+
+ /* Grab the first hit. */
+ return make_sam_from_nisp_object(pw_buf, &NIS_RES_OBJECT(result)[0]);
+}
+
+/*************************************************************************
+ sets a NIS+ attribute
+ *************************************************************************/
+static void set_single_attribute(nis_object *new_obj, int col,
+ char *val, int len, int flags)
+{
+ if (new_obj == NULL) return;
+
+ ENTRY_VAL(new_obj, col) = val;
+ ENTRY_LEN(new_obj, col) = len+1;
+
+ if (flags != 0)
+ {
+ new_obj->EN_data.en_cols.en_cols_val[col].ec_flags = flags;
+ }
+}
+
+/***************************************************************
+ copy or modify nis object. this object is used to add or update
+ nisplus table entry.
+ ****************************************************************/
+static BOOL init_nisp_from_sam(nis_object *obj, SAM_ACCOUNT *sampass,
+ nis_object *old)
+{
+ /*
+ * Fill nis_object for entry add or update.
+ * if we are updateing, we have to find out differences and set
+ * EN_MODIFIED flag. also set need_to_modify to trigger
+ * nis_modify_entry() call in pdb_update_sam_account().
+ *
+ * TODO:
+ * get data from SAM
+ * if (modify) get data from nis_object, compare and store if
+ * different + set EN_MODIFIED and need_to_modify
+ * else
+ * store
+ */
+ BOOL need_to_modify = False;
+ char *name; /* from SAM */
+ /* these must be static or allocate and free entry columns! */
+ static fstring uid; /* from SAM */
+ static fstring user_rid; /* from SAM */
+ static fstring gid; /* from SAM */
+ static fstring group_rid; /* from SAM */
+ char *acb; /* from SAM */
+ static fstring smb_passwd; /* from SAM */
+ static fstring smb_nt_passwd; /* from SAM */
+ static fstring logon_t; /* from SAM */
+ static fstring logoff_t; /* from SAM */
+ static fstring kickoff_t; /* from SAM */
+ static fstring pwdlset_t; /* from SAM */
+ static fstring pwdlchg_t; /* from SAM */
+ static fstring pwdmchg_t; /* from SAM */
+ static fstring full_name; /* from SAM */
+ static fstring acct_desc; /* from SAM */
+
+
+ name = pdb_get_username(sampass);
+ slprintf(uid, sizeof(uid)-1, "%u", pdb_get_uid(sampass));
+ slprintf(user_rid, sizeof(user_rid)-1, "%u",
+ pdb_get_user_rid(sampass)? pdb_get_user_rid(sampass):
+ pdb_uid_to_user_rid(pdb_get_uid(sampass)));
+ slprintf(gid, sizeof(gid)-1, "%u", pdb_get_gid(sampass));
+ slprintf(group_rid, sizeof(group_rid)-1, "%u",
+ pdb_get_group_rid(sampass)? pdb_get_group_rid(sampass):
+ pdb_gid_to_group_rid(pdb_get_gid(sampass)));
+ acb = pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sampass),
+ NEW_PW_FORMAT_SPACE_PADDED_LEN);
+ pdb_sethexpwd (smb_passwd, pdb_get_lanman_passwd(sampass),
+ pdb_get_acct_ctrl(sampass));
+ pdb_sethexpwd (smb_nt_passwd, pdb_get_nt_passwd(sampass),
+ pdb_get_acct_ctrl(sampass));
+ slprintf(logon_t, 13, "LNT-%08X",
+ (uint32)pdb_get_logon_time(sampass));
+ slprintf(logoff_t, 13, "LOT-%08X",
+ (uint32)pdb_get_logoff_time(sampass));
+ slprintf(kickoff_t, 13, "KOT-%08X",
+ (uint32)pdb_get_kickoff_time(sampass));
+ slprintf(pwdlset_t, 13, "LCT-%08X",
+ (uint32)pdb_get_pass_last_set_time(sampass));
+ slprintf(pwdlchg_t, 13, "CCT-%08X",
+ (uint32)pdb_get_pass_can_change_time(sampass));
+ slprintf(pwdmchg_t, 13, "MCT-%08X",
+ (uint32)pdb_get_pass_must_change_time(sampass));
+ safe_strcpy(full_name, pdb_get_fullname(sampass), sizeof(full_name)-1);
+ dos_to_unix(full_name, True);
+ safe_strcpy(acct_desc, pdb_get_acct_desc(sampass), sizeof(acct_desc)-1);
+ dos_to_unix(acct_desc, True);
+
+ if( old ) {
+ /* name */
+ if(strcmp(ENTRY_VAL(old, NPF_NAME), name))
+ {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_NAME, name, strlen(name),
+ EN_MODIFIED);
+ }
+
+
+ /* uid */
+ if(pdb_get_uid(sampass) != -1) {
+ if(!ENTRY_VAL(old, NPF_UID) || strcmp(ENTRY_VAL(old, NPF_UID), uid))
+ {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_UID, uid,
+ strlen(uid), EN_MODIFIED);
+ }
+ }
+
+ /* user_rid */
+ if (pdb_get_user_rid(sampass)) {
+ if(!ENTRY_VAL(old, NPF_USER_RID) ||
+ strcmp(ENTRY_VAL(old, NPF_USER_RID), user_rid) ) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_USER_RID, user_rid,
+ strlen(user_rid), EN_MODIFIED);
+ }
+ }
+
+ /* smb_grpid */
+ if (pdb_get_gid(sampass) != -1) {
+ if(!ENTRY_VAL(old, NPF_SMB_GRPID) ||
+ strcmp(ENTRY_VAL(old, NPF_SMB_GRPID), gid) ) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_SMB_GRPID, gid,
+ strlen(gid), EN_MODIFIED);
+ }
+ }
+
+ /* group_rid */
+ if (pdb_get_group_rid(sampass)) {
+ if(!ENTRY_VAL(old, NPF_GROUP_RID) ||
+ strcmp(ENTRY_VAL(old, NPF_GROUP_RID), group_rid) ) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_GROUP_RID, group_rid,
+ strlen(group_rid), EN_MODIFIED);
+ }
+ }
+
+ /* acb */
+ if (!ENTRY_VAL(old, NPF_ACB) ||
+ strcmp(ENTRY_VAL(old, NPF_ACB), acb)) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_ACB, acb, strlen(acb), EN_MODIFIED);
+ }
+
+ /* lmpwd */
+ if(!ENTRY_VAL(old, NPF_LMPWD) ||
+ strcmp(ENTRY_VAL(old, NPF_LMPWD), smb_passwd) ) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_LMPWD, smb_passwd,
+ strlen(smb_passwd), EN_CRYPT|EN_MODIFIED);
+ }
+
+ /* ntpwd */
+ if(!ENTRY_VAL(old, NPF_NTPWD) ||
+ strcmp(ENTRY_VAL(old, NPF_NTPWD), smb_nt_passwd) ) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
+ strlen(smb_nt_passwd), EN_CRYPT|EN_MODIFIED);
+ }
+
+ /* logon_t */
+ if( pdb_get_logon_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_LOGON_T) ||
+ strcmp(ENTRY_VAL(old, NPF_LOGON_T), logon_t ))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_LOGON_T, logon_t,
+ strlen(logon_t), EN_MODIFIED);
+ }
+
+ /* logoff_t */
+ if( pdb_get_logoff_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_LOGOFF_T) ||
+ strcmp(ENTRY_VAL(old, NPF_LOGOFF_T), logoff_t))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
+ strlen(logoff_t), EN_MODIFIED);
+ }
+
+ /* kick_t */
+ if( pdb_get_kickoff_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_KICK_T) ||
+ strcmp(ENTRY_VAL(old, NPF_KICK_T), kickoff_t))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_KICK_T, kickoff_t,
+ strlen(kickoff_t), EN_MODIFIED);
+ }
+
+ /* pwdlset_t */
+ if( pdb_get_pass_last_set_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_PWDLSET_T) ||
+ strcmp(ENTRY_VAL(old, NPF_PWDLSET_T), pwdlset_t))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
+ strlen(pwdlset_t), EN_MODIFIED);
+ }
+
+ /* pwdlchg_t */
+ if( pdb_get_pass_can_change_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_PWDCCHG_T) ||
+ strcmp(ENTRY_VAL(old, NPF_PWDCCHG_T), pwdlchg_t))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
+ strlen(pwdlchg_t), EN_MODIFIED);
+ }
+
+ /* pwdmchg_t */
+ if( pdb_get_pass_must_change_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_PWDMCHG_T) ||
+ strcmp(ENTRY_VAL(old, NPF_PWDMCHG_T), pwdmchg_t))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
+ strlen(pwdmchg_t), EN_MODIFIED);
+ }
+
+ /* full_name */
+ /* must support set, unset and change */
+ if ( (pdb_get_fullname(sampass) &&
+ !ENTRY_VAL(old, NPF_FULL_NAME)) ||
+ (ENTRY_VAL(old, NPF_FULL_NAME) &&
+ !pdb_get_fullname(sampass)) ||
+ (ENTRY_VAL(old, NPF_FULL_NAME) &&
+ pdb_get_fullname(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_FULL_NAME), full_name ))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_FULL_NAME, full_name,
+ strlen(full_name), EN_MODIFIED);
+ }
+
+ /* home_dir */
+ /* must support set, unset and change */
+ if( (pdb_get_homedir(sampass) &&
+ !ENTRY_VAL(old, NPF_HOME_DIR)) ||
+ (ENTRY_VAL(old, NPF_HOME_DIR) &&
+ !pdb_get_homedir(sampass)) ||
+ (ENTRY_VAL(old, NPF_HOME_DIR) &&
+ pdb_get_homedir(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_HOME_DIR),
+ pdb_get_homedir(sampass)))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_HOME_DIR, pdb_get_homedir(sampass),
+ strlen(pdb_get_homedir(sampass)), EN_MODIFIED);
+ }
+
+ /* dir_drive */
+ /* must support set, unset and change */
+ if( (pdb_get_dirdrive(sampass) &&
+ !ENTRY_VAL(old, NPF_DIR_DRIVE)) ||
+ (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
+ !pdb_get_dirdrive(sampass)) ||
+ (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
+ pdb_get_dirdrive(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE),
+ pdb_get_dirdrive(sampass)))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dirdrive(sampass),
+ strlen(pdb_get_dirdrive(sampass)), EN_MODIFIED);
+ }
+
+ /* logon_script */
+ /* must support set, unset and change */
+ if( (pdb_get_logon_script(sampass) &&
+ !ENTRY_VAL(old, NPF_LOGON_SCRIPT) ||
+ (ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
+ !pdb_get_logon_script(sampass)) ||
+ ( ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
+ pdb_get_logon_script(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_LOGON_SCRIPT),
+ pdb_get_logon_script(sampass))))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_LOGON_SCRIPT,
+ pdb_get_logon_script(sampass),
+ strlen(pdb_get_logon_script(sampass)),
+ EN_MODIFIED);
+ }
+
+ /* profile_path */
+ /* must support set, unset and change */
+ if( (pdb_get_profile_path(sampass) &&
+ !ENTRY_VAL(old, NPF_PROFILE_PATH)) ||
+ (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
+ !pdb_get_profile_path(sampass)) ||
+ (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
+ pdb_get_profile_path(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_PROFILE_PATH),
+ pdb_get_profile_path(sampass) ) )) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_PROFILE_PATH,
+ pdb_get_profile_path(sampass),
+ strlen(pdb_get_profile_path(sampass)),
+ EN_MODIFIED);
+ }
+
+ /* acct_desc */
+ /* must support set, unset and change */
+ if( (pdb_get_acct_desc(sampass) &&
+ !ENTRY_VAL(old, NPF_ACCT_DESC)) ||
+ (ENTRY_VAL(old, NPF_ACCT_DESC) &&
+ !pdb_get_acct_desc(sampass)) ||
+ (ENTRY_VAL(old, NPF_ACCT_DESC) &&
+ pdb_get_acct_desc(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_ACCT_DESC), acct_desc ) )) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_ACCT_DESC, acct_desc,
+ strlen(acct_desc), EN_MODIFIED);
+ }
+
+ /* workstations */
+ /* must support set, unset and change */
+ if ( (pdb_get_workstations(sampass) &&
+ !ENTRY_VAL(old, NPF_WORKSTATIONS) ) ||
+ (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
+ !pdb_get_workstations(sampass)) ||
+ (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
+ pdb_get_workstations(sampass)) &&
+ strcmp( ENTRY_VAL(old, NPF_WORKSTATIONS),
+ pdb_get_workstations(sampass))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_WORKSTATIONS,
+ pdb_get_workstations(sampass),
+ strlen(pdb_get_workstations(sampass)),
+ EN_MODIFIED);
+ }
+
+ /* hours */
+ if ((pdb_get_hours_len(sampass) != ENTRY_LEN(old, NPF_HOURS)) ||
+ memcmp(pdb_get_hours(sampass), ENTRY_VAL(old, NPF_HOURS),
+ ENTRY_LEN(old, NPF_HOURS))) {
+ need_to_modify = True;
+ /* set_single_attribute will add 1 for len ... */
+ set_single_attribute(obj, NPF_HOURS, pdb_get_hours(sampass),
+ pdb_get_hours_len(sampass)-1, EN_MODIFIED);
+ }
+ } else {
+ char empty[1];
+ char *homedir, *dirdrive, *logon_script, *profile_path, *workstations;
+
+ *empty = '\0'; /* empty string */
+
+ set_single_attribute(obj, NPF_NAME, name, strlen(name), 0);
+ set_single_attribute(obj, NPF_UID, uid, strlen(uid), 0);
+ set_single_attribute(obj, NPF_USER_RID, user_rid,
+ strlen(user_rid), 0);
+ set_single_attribute(obj, NPF_SMB_GRPID, gid, strlen(gid), 0);
+ set_single_attribute(obj, NPF_GROUP_RID, group_rid,
+ strlen(group_rid), 0);
+ set_single_attribute(obj, NPF_ACB, acb, strlen(acb), 0);
+ set_single_attribute(obj, NPF_LMPWD, smb_passwd,
+ strlen(smb_passwd), EN_CRYPT);
+ set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
+ strlen(smb_nt_passwd), EN_CRYPT);
+ set_single_attribute(obj, NPF_LOGON_T, logon_t,
+ strlen(logon_t), 0);
+ set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
+ strlen(logoff_t), 0);
+ set_single_attribute(obj, NPF_KICK_T, kickoff_t,
+ strlen(kickoff_t),0);
+ set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
+ strlen(pwdlset_t), 0);
+ set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
+ strlen(pwdlchg_t), 0);
+ set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
+ strlen(pwdmchg_t), 0);
+ set_single_attribute(obj, NPF_FULL_NAME ,
+ full_name, strlen(full_name), 0);
+
+ if(!(homedir = pdb_get_homedir(sampass)))
+ homedir = empty;
+
+ set_single_attribute(obj, NPF_HOME_DIR,
+ homedir, strlen(homedir), 0);
+
+ if(!(dirdrive = pdb_get_dirdrive(sampass)))
+ dirdrive = empty;
+
+ set_single_attribute(obj, NPF_DIR_DRIVE,
+ dirdrive, strlen(dirdrive), 0);
+
+ if(!(logon_script = pdb_get_logon_script(sampass)))
+ logon_script = empty;
+
+ set_single_attribute(obj, NPF_LOGON_SCRIPT,
+ logon_script, strlen(logon_script), 0);
+
+ if(!(profile_path = pdb_get_profile_path(sampass)))
+ profile_path = empty;
+
+ set_single_attribute(obj, NPF_PROFILE_PATH,
+ profile_path, strlen(profile_path), 0);
+
+ set_single_attribute(obj, NPF_ACCT_DESC,
+ acct_desc, strlen(acct_desc), 0);
+
+ if(!(workstations = pdb_get_workstations(sampass)))
+ workstations = empty;
+
+ set_single_attribute(obj, NPF_WORKSTATIONS,
+ workstations, strlen(workstations), 0);
+
+ /* set_single_attribute will add 1 for len ... */
+ set_single_attribute(obj, NPF_HOURS,
+ pdb_get_hours(sampass),
+ pdb_get_hours_len(sampass)-1, 0);
+ }
+
+ return need_to_modify;
+}
+
+/***************************************************************
+ calls nis_list, returns results.
+ ****************************************************************/
+static nis_result *nisp_get_nis_list(char *nis_name, uint_t flags)
+{
+ nis_result *result;
+ int i;
+
+ if( ! flags)
+ flags = FOLLOW_LINKS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP;
+
+ for(i = 0; i<2;i++ ) {
+ alarm(60); /* hopefully ok for long searches */
+ result = nis_list(nis_name, flags,NULL,NULL);
+
+ alarm(0);
+ CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
+
+ if (gotalarm)
+ {
+ DEBUG(0,("NIS+ lookup time out\n"));
+ nis_freeresult(result);
+ return NULL;
+ }
+ if( !(flags & MASTER_ONLY) && NIS_RES_NUMOBJ(result) <= 0 ) {
+ /* nis replicas are not in sync perhaps?
+ * this can happen, if account was just added.
+ */
+ DEBUG(10,("will try master only\n"));
+ nis_freeresult(result);
+ flags |= MASTER_ONLY;
+ } else
+ break;
+ }
+ return result;
+}
+
+/***************************************************************
+ Start to enumerate the nisplus passwd list.
+ ****************************************************************/
+BOOL pdb_setsampwent(BOOL update)
+{
+ char *sp, * p = lp_smb_passwd_file();
+ pstring pfiletmp;
+
+ if( (sp = strrchr( p, '/' )) )
+ safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
+ else
+ safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
+
+ pdb_endsampwent(); /* just in case */
+ global_nisp_ent.result = nisp_get_nis_list( pfiletmp, 0 );
+ global_nisp_ent.enum_entry = 0;
+ return global_nisp_ent.result != NULL ? True : False;
+}
+
+/***************************************************************
+ End enumeration of the nisplus passwd list.
+****************************************************************/
+void pdb_endsampwent(void)
+{
+ if( global_nisp_ent.result )
+ nis_freeresult(global_nisp_ent.result);
+ global_nisp_ent.result = NULL;
+ global_nisp_ent.enum_entry = 0;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the nisplus passwd list.
+ *************************************************************************/
+BOOL pdb_getsampwent(SAM_ACCOUNT *user)
+{
+ int enum_entry = (int)(global_nisp_ent.enum_entry);
+ nis_result *result = global_nisp_ent.result;
+
+ if (user==NULL) {
+ DEBUG(0,("SAM_ACCOUNT is NULL.\n"));
+ return False;
+ }
+
+ if (result == NULL ||
+ enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ(result) - 1))
+ {
+ return False;
+ }
+
+ if(!make_sam_from_nisp_object(user, &NIS_RES_OBJECT(result)[enum_entry]) )
+ {
+ DEBUG(0,("Bad SAM_ACCOUNT entry returned from NIS+!\n"));
+ return False;
+ }
+ (int)(global_nisp_ent.enum_entry)++;
+ return True;
+}
+
+/*************************************************************************
+ Routine to search the nisplus passwd file for an entry matching the username
+ *************************************************************************/
+BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname)
+{
+ /* Static buffers we will return. */
+ nis_result *result = NULL;
+ pstring nisname;
+ BOOL ret;
+ char *pfile = lp_smb_passwd_file();
+ int i;
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("No SMB password file set\n"));
+ return False;
+ }
+ if( strrchr( pfile, '/') )
+ pfile = strrchr( pfile, '/') + 1;
+
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile);
+ DEBUG(10, ("search by nisname: %s\n", nisname));
+
+ /* Search the table. */
+
+ if(!(result = nisp_get_nis_list(nisname, 0)))
+ {
+ return False;
+ }
+
+ ret = make_sam_from_nisresult(user, result);
+ nis_freeresult(result);
+
+ return ret;
+}
+
+/*************************************************************************
+ Routine to search the nisplus passwd file for an entry matching the username
+ *************************************************************************/
+BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
+{
+ nis_result *result;
+ char *nisname;
+ BOOL ret;
+ char *sp, *p = lp_smb_passwd_file();
+ pstring pfiletmp;
+
+ if (!*p)
+ {
+ DEBUG(0, ("no SMB password file set\n"));
+ return False;
+ }
+
+ if( (sp = strrchr( p, '/' )) )
+ safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
+ else
+ safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
+
+ nisname = make_nisname_from_user_rid(rid, pfiletmp);
+
+ DEBUG(10, ("search by rid: %s\n", nisname));
+
+ /* Search the table. */
+
+ if(!(result = nisp_get_nis_list(nisname, 0)))
+ {
+ return False;
+ }
+
+ ret = make_sam_from_nisresult(user, result);
+ nis_freeresult(result);
+
+ return ret;
+}
+
+/*************************************************************************
+ Routine to search the nisplus passwd file for an entry matching the username
+ *************************************************************************/
+BOOL pdb_getsampwuid(SAM_ACCOUNT * user, uid_t uid)
+{
+ nis_result *result;
+ char *nisname;
+ BOOL ret;
+ char *sp, *p = lp_smb_passwd_file();
+ pstring pfiletmp;
+
+ if (!*p)
+ {
+ DEBUG(0, ("no SMB password file set\n"));
+ return False;
+ }
+
+ if( (sp = strrchr( p, '/' )) )
+ safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
+ else
+ safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
+
+ nisname = make_nisname_from_uid(uid, pfiletmp);
+
+ DEBUG(10, ("search by uid: %s\n", nisname));
+
+ /* Search the table. */
+
+ if(!(result = nisp_get_nis_list(nisname, 0)))
+ {
+ return False;
+ }
+
+ ret = make_sam_from_nisresult(user, result);
+ nis_freeresult(result);
+
+ return ret;
+}
+
+/*************************************************************************
+ Routine to remove entry from the nisplus smbpasswd table
+ *************************************************************************/
+BOOL pdb_delete_sam_account(char *sname)
+{
+ char *pfile = lp_smb_passwd_file();
+ pstring nisname;
+ nis_result *result, *delresult;
+ nis_object *obj;
+ int i;
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("no SMB password file set\n"));
+ return False;
+ }
+ if( strrchr( pfile, '/') )
+ pfile = strrchr( pfile, '/') + 1;
+
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile);
+
+ /* Search the table. */
+
+ if( !(result = nisp_get_nis_list(nisname,
+ MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
+ EXPAND_NAME|HARD_LOOKUP))) {
+ return False;
+ }
+
+ if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
+ /* User not found. */
+ DEBUG(0,("user not found in NIS+\n"));
+ nis_freeresult(result);
+ return False;
+ }
+
+ obj = NIS_RES_OBJECT(result);
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s", sname, obj->zo_name,
+ obj->zo_domain);
+
+ DEBUG(10, ("removing name: %s\n", nisname));
+ delresult = nis_remove_entry(nisname, obj,
+ MASTER_ONLY|REM_MULTIPLE|ALL_RESULTS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
+
+ nis_freeresult(result);
+
+ if(delresult->status != NIS_SUCCESS) {
+ DEBUG(0, ("NIS+ table update failed: %s %s\n",
+ nisname, nis_sperrno(delresult->status)));
+ nis_freeresult(delresult);
+ return False;
+ }
+ nis_freeresult(delresult);
+ return True;
+}
+
+/************************************************************************
+ Routine to add an entry to the nisplus passwd file.
+*************************************************************************/
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
+{
+ int local_user = 0;
+ char *pfile;
+ pstring pfiletmp;
+ char *nisname;
+ nis_result *result = NULL,
+ *tblresult = NULL;
+ nis_object new_obj;
+ entry_col *ecol;
+ int ta_maxcol;
+
+ /*
+ * 1. find user domain.
+ * a. try nis search in passwd.org_dir - if found use domain from result.
+ * b. try getpwnam. this may be needed if user is defined
+ * in /etc/passwd file (or elsewere) and not in passwd.org_dir.
+ * if found, use host default domain.
+ * c. exit with False - no such user.
+ *
+ * 2. add user
+ * a. find smbpasswd table
+ * search pfile in user domain if not found, try host default
+ * domain.
+ * b. smbpasswd domain is found, fill data and add entry.
+ *
+ * pfile should contain ONLY table name, org_dir will be concated.
+ * so, at first we will clear path prefix from pfile, and
+ * then we will use pfiletmp as playground to put together full
+ * nisname string.
+ * such approach will make it possible to specify samba private dir
+ * AND still use NIS+ table. as all domain related data is normally
+ * stored in org_dir.DOMAIN, this should be ok do do.
+ */
+
+ pfile = lp_smb_passwd_file();
+ if( strrchr( pfile, '/') )
+ pfile = strrchr( pfile, '/') + 1;
+
+ /*
+ * Check if user is already there.
+ */
+ safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".org_dir",
+ sizeof(pfiletmp)-strlen(pfiletmp)-1);
+
+ if(pdb_get_username(newpwd) != NULL) {
+ nisname = make_nisname_from_name(pdb_get_username(newpwd),
+ pfiletmp);
+ } else {
+ return False;
+ }
+
+ if(!(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
+ return False;
+ }
+ if (result->status != NIS_SUCCESS &&
+ result->status != NIS_NOTFOUND) {
+ DEBUG(3, ( "nis_list failure: %s: %s\n",
+ nisname, nis_sperrno(result->status)));
+ nis_freeresult(result);
+ return False;
+ }
+
+ if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0)
+ {
+ DEBUG(3, ("User already exists in NIS+ password db: %s\n",
+ pfile));
+ nis_freeresult(result);
+ return False;
+ }
+
+ nis_freeresult(result); /* no such user, free results */
+
+ /*
+ * check for user in unix password database. we need this to get
+ * domain, where smbpasswd entry should be stored.
+ */
+
+ nisname = make_nisname_from_name(pdb_get_username(newpwd),
+ "passwd.org_dir");
+
+ result = nisp_get_nis_list(nisname,
+ MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
+ EXPAND_NAME|HARD_LOOKUP);
+
+ if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0)
+ {
+ DEBUG(3, ("nis_list failure: %s: %s\n",
+ nisname, nis_sperrno(result->status)));
+ nis_freeresult(result);
+
+ if (!sys_getpwnam(pdb_get_username(newpwd))) {
+ /* no such user in system! */
+ return False;
+ }
+ /*
+ * user is defined, but not in passwd.org_dir.
+ */
+ local_user = 1;
+ } else {
+ safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ safe_strcat(pfiletmp, NIS_RES_OBJECT(result)->zo_domain,
+ sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ nis_freeresult(result); /* not needed any more */
+
+ tblresult = nisp_get_nis_list(pfiletmp,
+ MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
+ }
+
+ if (local_user || tblresult->status != NIS_SUCCESS)
+ {
+ /*
+ * no user domain or
+ * smbpasswd table not found in user domain, fallback to
+ * default domain.
+ */
+ if (!local_user) /* free previous failed search result */
+ nis_freeresult(tblresult);
+
+ safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".org_dir",
+ sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ tblresult = nis_lookup(pfiletmp, MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
+ if (tblresult->status != NIS_SUCCESS)
+ {
+ /* still nothing. bail out */
+ nis_freeresult(tblresult);
+ DEBUG(3, ( "nis_lookup failure: %s\n",
+ nis_sperrno(tblresult->status)));
+ return False;
+ }
+ /* we need full name for nis_add_entry() */
+ safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ safe_strcat(pfiletmp, NIS_RES_OBJECT(tblresult)->zo_domain,
+ sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ }
+
+ memset((char *)&new_obj, 0, sizeof (new_obj));
+ /* fill entry headers */
+ /* we do not free these. */
+ new_obj.zo_name = NIS_RES_OBJECT(tblresult)->zo_name;
+ new_obj.zo_owner = NIS_RES_OBJECT(tblresult)->zo_owner;
+ new_obj.zo_group = NIS_RES_OBJECT(tblresult)->zo_group;
+ new_obj.zo_domain = NIS_RES_OBJECT(tblresult)->zo_domain;
+ /* uints */
+ new_obj.zo_access = NIS_RES_OBJECT(tblresult)->zo_access;
+ new_obj.zo_ttl = NIS_RES_OBJECT(tblresult)->zo_ttl;
+
+ new_obj.zo_data.zo_type = ENTRY_OBJ;
+ new_obj.EN_data.en_type =
+ NIS_RES_OBJECT(tblresult)->TA_data.ta_type;
+
+ ta_maxcol = NIS_RES_OBJECT(tblresult)->TA_data.ta_maxcol;
+
+ if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
+ DEBUG(0, ("memory allocation failure\n"));
+ nis_freeresult(tblresult);
+ return False;
+ }
+
+ memset((char *)ecol, 0, ta_maxcol*sizeof (entry_col));
+ new_obj.EN_data.en_cols.en_cols_val = ecol;
+ new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
+
+ init_nisp_from_sam(&new_obj, newpwd, NULL);
+
+ DEBUG(10, ( "add NIS+ entry: %s\n", nisname));
+ result = nis_add_entry(pfiletmp, &new_obj, 0);
+
+ free(ecol); /* free allocated entry space */
+
+ if (result->status != NIS_SUCCESS)
+ {
+ DEBUG(3, ( "NIS+ table update failed: %s\n",
+ nisname, nis_sperrno(result->status)));
+ nis_freeresult(tblresult);
+ nis_freeresult(result);
+ return False;
+ }
+
+ nis_freeresult(tblresult);
+ nis_freeresult(result);
+
+ return True;
+}
+
+/************************************************************************
+ Routine to modify the nisplus passwd entry.
+************************************************************************/
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
+{
+ nis_result *result, *addresult;
+ nis_object *obj;
+ nis_object new_obj;
+ entry_col *ecol;
+ int ta_maxcol;
+ char *pfile = lp_smb_passwd_file();
+ pstring nisname;
+ int i;
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("no SMB password file set\n"));
+ return False;
+ }
+ if( strrchr( pfile, '/') )
+ pfile = strrchr( pfile, '/') + 1;
+
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir",
+ pdb_get_username(newpwd), pfile);
+
+ DEBUG(10, ("search by name: %s\n", nisname));
+
+ /* Search the table. */
+
+ if( !(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
+ return False;
+ }
+
+ if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
+ /* User not found. */
+ DEBUG(0,("user not found in NIS+\n"));
+ nis_freeresult(result);
+ return False;
+ }
+
+ obj = NIS_RES_OBJECT(result);
+ DEBUG(6,("entry found in %s\n", obj->zo_domain));
+
+ /* we must create new stub object with EN_MODIFIED flag.
+ this is because obj from result is going to be freed and
+ we do not want to break it or cause memory leaks or corruption.
+ */
+
+ memmove((char *)&new_obj, obj, sizeof (new_obj));
+ ta_maxcol = obj->TA_data.ta_maxcol;
+
+ if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
+ DEBUG(0, ("memory allocation failure\n"));
+ nis_freeresult(result);
+ return False;
+ }
+
+ memmove((char *)ecol, obj->EN_data.en_cols.en_cols_val,
+ ta_maxcol*sizeof (entry_col));
+ new_obj.EN_data.en_cols.en_cols_val = ecol;
+ new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
+
+ if ( init_nisp_from_sam(&new_obj, newpwd, obj) == True ) {
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s",
+ pdb_get_username(newpwd), pfile, obj->zo_domain);
+
+ DEBUG(10, ("NIS+ table update: %s\n", nisname));
+ addresult =
+ nis_modify_entry(nisname, &new_obj,
+ MOD_SAMEOBJ | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
+
+ if(addresult->status != NIS_SUCCESS) {
+ DEBUG(0, ("NIS+ table update failed: %s %s\n",
+ nisname, nis_sperrno(addresult->status)));
+ nis_freeresult(addresult);
+ nis_freeresult(result);
+ free(ecol);
+ return False;
+ }
+
+ DEBUG(6,("password changed\n"));
+ nis_freeresult(addresult);
+ } else {
+ DEBUG(6,("nothing to change!\n"));
+ }
+
+ free(ecol);
+ nis_freeresult(result);
+
+ return True;
+}
+
+#else
+ void nisplus_dummy_function(void);
+ void nisplus_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* WITH_NISPLUSSAM */
+
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index 7c95feb8ca6..bca7541782a 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -22,7 +22,7 @@
#include "includes.h"
-#ifdef USE_SMBPASS_DB
+#ifdef WITH_SMBPASSWD_SAM
/*
@@ -54,10 +54,6 @@ extern struct passdb_ops pdb_ops;
static int pw_file_lock_depth;
static void *global_vp;
-/* static memory area used by all passdb search functions
- in this module */
-/*static SAM_ACCOUNT global_sam_pass;*/
-
enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE };
@@ -414,7 +410,7 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
pw_buf.smb_passwd = NULL;
pw_buf.acct_ctrl |= ACB_PWNOTREQ;
} else {
- if (!smbpasswd_gethexpwd((char *)p, smbpwd)) {
+ if (!pdb_gethexpwd((char *)p, smbpwd)) {
DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
continue;
}
@@ -431,7 +427,7 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
the lanman password. */
if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
if (*p != '*' && *p != 'X') {
- if(smbpasswd_gethexpwd((char *)p,smbntpwd))
+ if(pdb_gethexpwd((char *)p,smbntpwd))
pw_buf.smb_nt_passwd = smbntpwd;
}
p += 33; /* Move to the first character of the line after
@@ -444,7 +440,7 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
if (*p == '[')
{
unsigned char *end_p = (unsigned char *)strchr_m((char *)p, ']');
- pw_buf.acct_ctrl = smbpasswd_decode_acb_info((char*)p);
+ pw_buf.acct_ctrl = pdb_decode_acct_ctrl((char*)p);
/* Must have some account type set. */
if(pw_buf.acct_ctrl == 0)
@@ -545,8 +541,8 @@ static char *format_new_smbpasswd_entry(struct smb_passwd *newpwd)
*p++ = ':';
/* Add the account encoding and the last change time. */
- slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n",
- smbpasswd_encode_acb_info(newpwd->acct_ctrl),
+ slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n",
+ pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN),
(uint32)newpwd->pass_last_set_time);
return new_entry;
@@ -640,11 +636,11 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
}
endsmbfilepwent(fp, &pw_file_lock_depth);
- SAFE_FREE(new_entry);
+ free(new_entry);
return False;
}
- SAFE_FREE(new_entry);
+ free(new_entry);
endsmbfilepwent(fp, &pw_file_lock_depth);
return True;
}
@@ -903,7 +899,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
* acct ctrl field. Encode the given acct ctrl
* bits into it.
*/
- fstrcpy(encode_bits, smbpasswd_encode_acb_info(pwd->acct_ctrl));
+ fstrcpy(encode_bits, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
} else {
/*
* If using the old format and the ACB_DISABLED or
@@ -1121,11 +1117,11 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
unlink(pfile2);
endsmbfilepwent(fp, &pw_file_lock_depth);
endsmbfilepwent(fp_write, &pfile2_lockdepth);
- SAFE_FREE(new_entry);
+ free(new_entry);
return False;
}
- SAFE_FREE(new_entry);
+ free(new_entry);
}
/*
@@ -1298,7 +1294,6 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
{
struct smb_passwd *pw_buf=NULL;
BOOL done = False;
-
DEBUG(5,("pdb_getsampwent\n"));
if (user==NULL) {
@@ -1309,11 +1304,6 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
return False;
}
- /* do we have an entry? */
- pw_buf = getsmbfilepwent(global_vp);
- if (pw_buf == NULL)
- return False;
-
while (!done)
{
/* do we have an entry? */
@@ -1530,4 +1520,4 @@ BOOL pdb_delete_sam_account (char* username)
#else
/* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
void smbpass_dummy_function(void) { } /* stop some compilers complaining */
-#endif /* USE_SMBPASS_DB */
+#endif /* WTH_SMBPASSWD_SAM*/
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index cf2a7f2ec11..700a241be87 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -3,6 +3,7 @@
* Copyright (C) Andrew Tridgell 1992-1998
* Copyright (C) Simo Sorce 2000
* Copyright (C) Gerald Carter 2000
+ * Copyright (C) Jeremy Allison 2001
*
* 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
@@ -21,7 +22,7 @@
#include "includes.h"
-#ifdef WITH_TDBSAM
+#ifdef WITH_TDB_SAM
#define PDB_VERSION "20010830"
#define PASSDB_FILE_NAME "/passdb.tdb"
@@ -33,9 +34,7 @@ extern int DEBUGLEVEL;
extern pstring samlogon_user;
extern BOOL sam_logon_in_ssb;
-
-struct tdb_enum_info
-{
+struct tdb_enum_info {
TDB_CONTEXT *passwd_tdb;
TDB_DATA key;
};
@@ -46,8 +45,8 @@ static struct tdb_enum_info global_tdb_ent;
/**********************************************************************
Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
*********************************************************************/
-static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf,
- uint32 buflen)
+
+static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
{
/* times are stored as 32bit integer
@@ -79,11 +78,10 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf,
uint32 /* uid, gid,*/ user_rid, group_rid, unknown_3, hours_len, unknown_5, unknown_6;
uint16 acct_ctrl, logon_divs;
uint8 *hours;
- static uint8 *lm_pw_ptr,
- *nt_pw_ptr;
+ static uint8 *lm_pw_ptr, *nt_pw_ptr;
uint32 len = 0;
uint32 lmpwlen, ntpwlen, hourslen;
-
+ BOOL ret = True;
/* unpack the buffer into variables */
len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING,
@@ -117,8 +115,10 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf,
&unknown_5,
&unknown_6);
- if (len == -1)
- return False;
+ if (len == -1) {
+ ret = False;
+ goto done;
+ }
pdb_set_logon_time(sampass, logon_time);
pdb_set_logoff_time(sampass, logoff_time);
@@ -153,9 +153,21 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf,
pdb_set_logons_divs(sampass, logon_divs);
pdb_set_hours(sampass, hours);
- /* TODO: free TDB alloced memory !!!!! */
-
- return True;
+done:
+
+ SAFE_FREE(username);
+ SAFE_FREE(domain);
+ SAFE_FREE(nt_username);
+ SAFE_FREE(fullname);
+ SAFE_FREE(homedir);
+ SAFE_FREE(dir_drive);
+ SAFE_FREE(logon_script);
+ SAFE_FREE(profile_path);
+ SAFE_FREE(acct_desc);
+ SAFE_FREE(workstations);
+ SAFE_FREE(munged_dial);
+
+ return ret;
}
/**********************************************************************
@@ -203,56 +215,80 @@ static uint32 init_buffer_from_sam (uint8 **buf, SAM_ACCOUNT *sampass)
*buf = NULL;
buflen = 0;
- logon_time = pdb_get_logon_time(sampass);
- logoff_time = pdb_get_logoff_time(sampass);
- kickoff_time = pdb_get_kickoff_time(sampass);
- pass_can_change_time = pdb_get_pass_can_change_time(sampass);
- pass_must_change_time = pdb_get_pass_must_change_time(sampass);
- pass_last_set_time = pdb_get_pass_last_set_time(sampass);
+ logon_time = (uint32)pdb_get_logon_time(sampass);
+ logoff_time = (uint32)pdb_get_logoff_time(sampass);
+ kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
+ pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
+ pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
+ pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
username = pdb_get_username(sampass);
- if (username) username_len = strlen(username) +1;
- else username_len = 0;
+ if (username)
+ username_len = strlen(username) +1;
+ else
+ username_len = 0;
domain = pdb_get_domain(sampass);
- if (domain) domain_len = strlen(domain) +1;
- else domain_len = 0;
+ if (domain)
+ domain_len = strlen(domain) +1;
+ else
+ domain_len = 0;
nt_username = pdb_get_nt_username(sampass);
- if (nt_username) nt_username_len = strlen(nt_username) +1;
- else nt_username_len = 0;
+ if (nt_username)
+ nt_username_len = strlen(nt_username) +1;
+ else
+ nt_username_len = 0;
dir_drive = pdb_get_dirdrive(sampass);
- if (dir_drive) dir_drive_len = strlen(dir_drive) +1;
- else dir_drive_len = 0;
+ if (dir_drive)
+ dir_drive_len = strlen(dir_drive) +1;
+ else
+ dir_drive_len = 0;
unknown_str = NULL;
unknown_str_len = 0;
munged_dial = pdb_get_munged_dial(sampass);
- if (munged_dial) munged_dial_len = strlen(munged_dial) +1;
- else munged_dial_len = 0;
+ if (munged_dial)
+ munged_dial_len = strlen(munged_dial) +1;
+ else
+ munged_dial_len = 0;
fullname = pdb_get_fullname(sampass);
- if (fullname) fullname_len = strlen(fullname) +1;
- else fullname_len = 0;
+ if (fullname)
+ fullname_len = strlen(fullname) +1;
+ else
+ fullname_len = 0;
homedir = pdb_get_homedir(sampass);
- if (homedir) homedir_len = strlen(homedir) +1;
- else homedir_len = 0;
+ if (homedir)
+ homedir_len = strlen(homedir) +1;
+ else
+ homedir_len = 0;
logon_script = pdb_get_logon_script(sampass);
- if (logon_script) logon_script_len = strlen(logon_script) +1;
- else logon_script_len = 0;
+ if (logon_script)
+ logon_script_len = strlen(logon_script) +1;
+ else
+ logon_script_len = 0;
profile_path = pdb_get_profile_path(sampass);
- if (profile_path) profile_path_len = strlen(profile_path) +1;
- else profile_path_len = 0;
+ if (profile_path)
+ profile_path_len = strlen(profile_path) +1;
+ else
+ profile_path_len = 0;
acct_desc = pdb_get_acct_desc(sampass);
- if (acct_desc) acct_desc_len = strlen(acct_desc) +1;
- else acct_desc_len = 0;
+ if (acct_desc)
+ acct_desc_len = strlen(acct_desc) +1;
+ else
+ acct_desc_len = 0;
workstations = pdb_get_workstations(sampass);
- if (workstations) workstations_len = strlen(workstations) +1;
- else workstations_len = 0;
+ if (workstations)
+ workstations_len = strlen(workstations) +1;
+ else
+ workstations_len = 0;
lm_pw = pdb_get_lanman_passwd(sampass);
- if (!lm_pw) lm_pw_len = 0;
+ if (!lm_pw)
+ lm_pw_len = 0;
nt_pw = pdb_get_nt_passwd(sampass);
- if (!nt_pw) nt_pw_len = 0;
+ if (!nt_pw)
+ nt_pw_len = 0;
/* one time to get the size needed */
len = tdb_pack(NULL, 0, TDB_FORMAT_STRING,
@@ -288,8 +324,7 @@ static uint32 init_buffer_from_sam (uint8 **buf, SAM_ACCOUNT *sampass)
/* malloc the space needed */
- if ( (*buf=(uint8*)malloc(len)) == NULL)
- {
+ if ( (*buf=(uint8*)malloc(len)) == NULL) {
DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n"));
return (-1);
}
@@ -328,8 +363,7 @@ static uint32 init_buffer_from_sam (uint8 **buf, SAM_ACCOUNT *sampass)
/* check to make sure we got it correct */
- if (buflen != len)
- {
+ if (buflen != len) {
/* error */
SAFE_FREE (*buf);
return (-1);
@@ -341,19 +375,18 @@ static uint32 init_buffer_from_sam (uint8 **buf, SAM_ACCOUNT *sampass)
/***************************************************************
Open the TDB passwd database for SAM account enumeration.
****************************************************************/
+
BOOL pdb_setsampwent(BOOL update)
{
pstring tdbfile;
- pstrcpy (tdbfile, lp_private_dir());
+ get_private_directory(tdbfile);
pstrcat (tdbfile, PASSDB_FILE_NAME);
/* Open tdb passwd */
- if (!(global_tdb_ent.passwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, update ? O_RDWR : O_RDONLY, 0600)))
- {
+ if (!(global_tdb_ent.passwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, update ? O_RDWR : O_RDONLY, 0600))) {
DEBUG(0, ("Unable to open TDB passwd, trying create new!\n"));
- if (!(global_tdb_ent.passwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT | O_EXCL, 0600)))
- {
+ if (!(global_tdb_ent.passwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT | O_EXCL, 0600))) {
DEBUG(0, ("Unable to create TDB passwd (passdb.tdb) !!!"));
return False;
}
@@ -367,10 +400,10 @@ BOOL pdb_setsampwent(BOOL update)
/***************************************************************
End enumeration of the TDB passwd list.
****************************************************************/
+
void pdb_endsampwent(void)
{
- if (global_tdb_ent.passwd_tdb)
- {
+ if (global_tdb_ent.passwd_tdb) {
tdb_close(global_tdb_ent.passwd_tdb);
global_tdb_ent.passwd_tdb = NULL;
}
@@ -378,10 +411,10 @@ void pdb_endsampwent(void)
DEBUG(7, ("endtdbpwent: closed password file.\n"));
}
-
/*****************************************************************
Get one SAM_ACCOUNT from the TDB (next in line)
*****************************************************************/
+
BOOL pdb_getsampwent(SAM_ACCOUNT *user)
{
TDB_DATA data;
@@ -402,22 +435,19 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
global_tdb_ent.key = tdb_nextkey (global_tdb_ent.passwd_tdb, global_tdb_ent.key);
/* do we have an valid interation pointer? */
- if(global_tdb_ent.passwd_tdb == NULL)
- {
+ if(global_tdb_ent.passwd_tdb == NULL) {
DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
return False;
}
data = tdb_fetch (global_tdb_ent.passwd_tdb, global_tdb_ent.key);
- if (!data.dptr)
- {
+ if (!data.dptr) {
DEBUG(5,("pdb_getsampwent: database entry not found.\n"));
return False;
}
/* unpack the buffer */
- if (!init_sam_from_buffer (user, data.dptr, data.dsize))
- {
+ if (!init_sam_from_buffer (user, data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
return False;
@@ -427,8 +457,7 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
/* validate the account and fill in UNIX uid and gid. sys_getpwnam()
is used instaed of Get_Pwnam() as we do not need to try case
permutations */
- if ((pw=sys_getpwnam(pdb_get_username(user))) == NULL)
- {
+ if ((pw=sys_getpwnam(pdb_get_username(user))) == NULL) {
DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n",
pdb_get_username(user)));
return False;
@@ -455,6 +484,7 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
/******************************************************************
Lookup a name in the SAM TDB
******************************************************************/
+
BOOL pdb_getsampwnam (SAM_ACCOUNT *user, char *sname)
{
TDB_CONTEXT *pwd_tdb;
@@ -473,8 +503,7 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, char *sname)
}
fstrcpy (name, sname);
- strlower (name);
- pstrcpy (tdbfile, lp_private_dir());
+ get_private_directory(tdbfile);
pstrcat (tdbfile, PASSDB_FILE_NAME);
/* set search key */
@@ -483,16 +512,14 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, char *sname)
key.dsize = strlen (keystr) + 1;
/* open the accounts TDB */
- if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600)))
- {
+ if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd!\n"));
return False;
}
/* get the record */
data = tdb_fetch (pwd_tdb, key);
- if (!data.dptr)
- {
+ if (!data.dptr) {
DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close (pwd_tdb);
@@ -500,8 +527,7 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, char *sname)
}
/* unpack the buffer */
- if (!init_sam_from_buffer (user, data.dptr, data.dsize))
- {
+ if (!init_sam_from_buffer (user, data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
return False;
@@ -511,8 +537,7 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, char *sname)
/* validate the account and fill in UNIX uid and gid. sys_getpwnam()
is used instaed of Get_Pwnam() as we do not need to try case
permutations */
- if ((pw=sys_getpwnam(pdb_get_username(user))) == NULL)
- {
+ if ((pw=sys_getpwnam(pdb_get_username(user))) == NULL) {
DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n",
pdb_get_username(user)));
return False;
@@ -539,6 +564,7 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, char *sname)
/***************************************************************************
Search by uid
**************************************************************************/
+
BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid)
{
struct passwd *pw;
@@ -550,8 +576,7 @@ BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid)
}
pw = sys_getpwuid(uid);
- if (pw == NULL)
- {
+ if (pw == NULL) {
DEBUG(0,("pdb_getsampwuid: getpwuid(%d) return NULL. User does not exist!\n", uid));
return False;
}
@@ -564,6 +589,7 @@ BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid)
/***************************************************************************
Search by rid
**************************************************************************/
+
BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
{
TDB_CONTEXT *pwd_tdb;
@@ -577,7 +603,7 @@ BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
return False;
}
- pstrcpy (tdbfile, lp_private_dir());
+ get_private_directory(tdbfile);
pstrcat (tdbfile, PASSDB_FILE_NAME);
/* set search key */
@@ -586,16 +612,14 @@ BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
key.dsize = strlen (keystr) + 1;
/* open the accounts TDB */
- if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600)))
- {
+ if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n"));
return False;
}
/* get the record */
data = tdb_fetch (pwd_tdb, key);
- if (!data.dptr)
- {
+ if (!data.dptr) {
DEBUG(5,("pdb_getsampwrid (TDB): error fetching database.\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close (pwd_tdb);
@@ -610,10 +634,10 @@ BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
return pdb_getsampwnam (user, name);
}
-
/***************************************************************************
Delete a SAM_ACCOUNT
****************************************************************************/
+
BOOL pdb_delete_sam_account(char *sname)
{
SAM_ACCOUNT *sam_pass = NULL;
@@ -627,12 +651,11 @@ BOOL pdb_delete_sam_account(char *sname)
fstrcpy (name, sname);
strlower (name);
- pstrcpy (tdbfile, lp_private_dir());
+ get_private_directory(tdbfile);
pstrcat (tdbfile, PASSDB_FILE_NAME);
/* open the TDB */
- if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0600)))
- {
+ if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0600))) {
DEBUG(0, ("Unable to open TDB passwd!"));
return False;
}
@@ -644,8 +667,7 @@ BOOL pdb_delete_sam_account(char *sname)
/* get the record */
data = tdb_fetch (pwd_tdb, key);
- if (!data.dptr)
- {
+ if (!data.dptr) {
DEBUG(5,("pdb_delete_sam_account (TDB): error fetching database.\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close (pwd_tdb);
@@ -653,14 +675,12 @@ BOOL pdb_delete_sam_account(char *sname)
}
/* unpack the buffer */
- if (!pdb_init_sam (&sam_pass))
- {
+ if (!pdb_init_sam (&sam_pass)) {
tdb_close (pwd_tdb);
return False;
}
- if (!init_sam_from_buffer (sam_pass, data.dptr, data.dsize))
- {
+ if (!init_sam_from_buffer (sam_pass, data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
tdb_close (pwd_tdb);
SAFE_FREE(data.dptr);
@@ -673,8 +693,7 @@ BOOL pdb_delete_sam_account(char *sname)
pdb_free_sam (sam_pass);
/* it's outaa here! 8^) */
- if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS)
- {
+ if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) {
DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close(pwd_tdb);
@@ -689,8 +708,7 @@ BOOL pdb_delete_sam_account(char *sname)
key.dsize = strlen (keystr) + 1;
/* it's outaa here! 8^) */
- if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS)
- {
+ if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) {
DEBUG(5, ("Error deleting entry from tdb rid database!\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close(pwd_tdb);
@@ -705,6 +723,7 @@ BOOL pdb_delete_sam_account(char *sname)
/***************************************************************************
Update the TDB SAM
****************************************************************************/
+
static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
{
TDB_CONTEXT *pwd_tdb;
@@ -716,7 +735,7 @@ static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
BOOL ret = True;
int newtdb = FALSE;
- pstrcpy (tdbfile, lp_private_dir());
+ get_private_directory(tdbfile);
pstrcat (tdbfile, PASSDB_FILE_NAME);
if ( (!newpwd->uid) || (!newpwd->gid) )
@@ -729,10 +748,8 @@ static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
if (!newpwd->group_rid)
pdb_set_group_rid (newpwd, pdb_gid_to_group_rid (newpwd->gid));
-
/* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */
- if ((data.dsize=init_buffer_from_sam (&buf, newpwd)) == -1)
- {
+ if ((data.dsize=init_buffer_from_sam (&buf, newpwd)) == -1) {
DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n"));
ret = False;
goto done;
@@ -748,21 +765,17 @@ static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
key.dsize = strlen (keystr) + 1;
/* invalidate the existing TDB iterator if it is open */
- if (global_tdb_ent.passwd_tdb)
- {
+ if (global_tdb_ent.passwd_tdb) {
tdb_close(global_tdb_ent.passwd_tdb);
global_tdb_ent.passwd_tdb = NULL;
}
/* open the account TDB passwd*/
- if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0600)))
- {
- DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd!\n"));
- if (flag == TDB_INSERT)
- {
+ if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0600))) {
+ DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd!\n"));
+ if (flag == TDB_INSERT) {
DEBUG(0, ("Unable to open TDB passwd, trying create new!\n"));
- if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT | O_EXCL, 0600)))
- {
+ if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT | O_EXCL, 0600))) {
DEBUG(0, ("Unable to create TDB passwd (passdb.tdb) !!!\n"));
ret = False;
goto done;
@@ -772,8 +785,7 @@ static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
}
/* add the account */
- if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS)
- {
+ if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
DEBUG(0, ("Unable to modify passwd TDB!"));
DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close (pwd_tdb);
@@ -791,8 +803,7 @@ static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
key.dsize = strlen (keystr) + 1;
/* add the reference */
- if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS)
- {
+ if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
DEBUG(0, ("Unable to modify TDB passwd !"));
DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
ret = False;
@@ -800,17 +811,17 @@ static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
}
done:
+
/* cleanup */
tdb_close (pwd_tdb);
SAFE_FREE(buf);
-
return (ret);
-
}
/***************************************************************************
Modifies an existing SAM_ACCOUNT
****************************************************************************/
+
BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override)
{
return (tdb_update_sam(newpwd, override, TDB_MODIFY));
@@ -819,13 +830,13 @@ BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override)
/***************************************************************************
Adds an existing SAM_ACCOUNT
****************************************************************************/
+
BOOL pdb_add_sam_account (SAM_ACCOUNT *newpwd)
{
return (tdb_update_sam(newpwd, True, TDB_INSERT));
}
-
#else
/* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
void samtdb_dummy_function(void) { } /* stop some compilers complaining */
-#endif /* WITH_TDBSAM */
+#endif /* WITH_TDB_SAM */