summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/dummysmbd.c9
-rw-r--r--source3/lib/events.c125
-rw-r--r--source3/lib/genrand.c4
-rw-r--r--source3/lib/messages.c15
-rw-r--r--source3/lib/pam_errors.c1
-rw-r--r--source3/lib/pidfile.c6
-rw-r--r--source3/lib/readline.c4
-rw-r--r--source3/lib/secdesc.c10
-rw-r--r--source3/lib/sharesec.c308
-rw-r--r--source3/lib/smbldap.c221
-rw-r--r--source3/lib/smbldap_util.c92
-rw-r--r--source3/lib/system_smbd.c91
-rw-r--r--source3/lib/username.c124
-rw-r--r--source3/lib/util.c8
-rw-r--r--source3/lib/util_file.c33
-rw-r--r--source3/lib/util_pw.c79
-rw-r--r--source3/lib/util_sid.c5
-rw-r--r--source3/lib/util_str.c99
-rw-r--r--source3/lib/util_unistr.c14
19 files changed, 920 insertions, 328 deletions
diff --git a/source3/lib/dummysmbd.c b/source3/lib/dummysmbd.c
index 1b31dff499..9b587224e3 100644
--- a/source3/lib/dummysmbd.c
+++ b/source3/lib/dummysmbd.c
@@ -29,3 +29,12 @@ void decrement_smbd_process_count( void )
return;
}
+int find_service(fstring service)
+{
+ return -1;
+}
+
+BOOL conn_snum_used(int snum)
+{
+ return False;
+}
diff --git a/source3/lib/events.c b/source3/lib/events.c
new file mode 100644
index 0000000000..314f074979
--- /dev/null
+++ b/source3/lib/events.c
@@ -0,0 +1,125 @@
+/*
+ Unix SMB/CIFS implementation.
+ Timed event library.
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Volker Lendecke 2005
+
+ 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"
+
+static struct timed_event *timed_events;
+
+static int timed_event_destructor(void *p)
+{
+ struct timed_event *te = talloc_get_type_abort(p, struct timed_event);
+ DEBUG(10, ("Destroying timed event %lx \"%s\"\n", (unsigned long)te,
+ te->event_name));
+ DLIST_REMOVE(timed_events, te);
+ return 0;
+}
+
+/****************************************************************************
+ Schedule a function for future calling, cancel with talloc_free().
+ It's the responsibility of the handler to call talloc_free() on the event
+ handed to it.
+****************************************************************************/
+
+struct timed_event *add_timed_event(TALLOC_CTX *mem_ctx,
+ struct timeval when,
+ const char *event_name,
+ void (*handler)(struct timed_event *te,
+ const struct timeval *now,
+ void *private_data),
+ void *private_data)
+{
+ struct timed_event *te, *last_te, *cur_te;
+
+ te = TALLOC_P(mem_ctx, struct timed_event);
+ if (te == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
+
+ te->when = when;
+ te->event_name = event_name;
+ te->handler = handler;
+ te->private_data = private_data;
+
+ /* keep the list ordered */
+ last_te = NULL;
+ for (cur_te = timed_events; cur_te; cur_te = cur_te->next) {
+ /* if the new event comes before the current one break */
+ if (!timeval_is_zero(&cur_te->when) &&
+ timeval_compare(&te->when, &cur_te->when) < 0) {
+ break;
+ }
+ last_te = cur_te;
+ }
+
+ DLIST_ADD_AFTER(timed_events, te, last_te);
+ talloc_set_destructor(te, timed_event_destructor);
+
+ DEBUG(10, ("Added timed event \"%s\": %lx\n", event_name,
+ (unsigned long)te));
+ return te;
+}
+
+void run_events(void)
+{
+ struct timeval now;
+
+ if (timed_events == NULL) {
+ /* No syscall if there are no events */
+ DEBUG(10, ("run_events: No events\n"));
+ return;
+ }
+
+ GetTimeOfDay(&now);
+
+ if (timeval_compare(&now, &timed_events->when) < 0) {
+ /* Nothing to do yet */
+ DEBUG(10, ("run_events: Nothing to do\n"));
+ return;
+ }
+
+ DEBUG(10, ("Running event \"%s\" %lx\n", timed_events->event_name,
+ (unsigned long)timed_events));
+
+ timed_events->handler(timed_events, &now, timed_events->private_data);
+ return;
+}
+
+struct timeval *get_timed_events_timeout(struct timeval *to_ret, time_t default_to)
+{
+ struct timeval now;
+
+ if (timed_events == NULL) {
+ if (default_to == (time_t)-1) {
+ return NULL;
+ }
+ *to_ret = timeval_set(default_to, 0);
+ return to_ret;
+ }
+
+ now = timeval_current();
+ *to_ret = timeval_until(&now, &timed_events->when);
+
+ DEBUG(10, ("timed_events_timeout: %d/%d\n", (int)to_ret->tv_sec,
+ (int)to_ret->tv_usec));
+
+ return to_ret;
+}
diff --git a/source3/lib/genrand.c b/source3/lib/genrand.c
index f37bbc9c2f..5b643bf297 100644
--- a/source3/lib/genrand.c
+++ b/source3/lib/genrand.c
@@ -114,14 +114,14 @@ static int do_reseed(BOOL use_fd, int fd)
* seriously this will be secret.
*/
- pw = getpwnam_alloc("root");
+ pw = getpwnam_alloc(NULL, "root");
if (pw && pw->pw_passwd) {
size_t i;
unsigned char md4_tmp[16];
mdfour(md4_tmp, (unsigned char *)pw->pw_passwd, strlen(pw->pw_passwd));
for (i=0;i<16;i++)
seed_inbuf[8+i] ^= md4_tmp[i];
- passwd_free(&pw);
+ talloc_free(pw);
}
/*
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 058bbc99b0..2d6518aed6 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -604,4 +604,19 @@ BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type,
*n_sent = msg_all.n_sent;
return True;
}
+
+/*
+ * Block and unblock receiving of messages. Allows removal of race conditions
+ * when doing a fork and changing message disposition.
+ */
+
+void message_block(void)
+{
+ BlockSignals(True, SIGUSR1);
+}
+
+void message_unblock(void)
+{
+ BlockSignals(False, SIGUSR1);
+}
/** @} **/
diff --git a/source3/lib/pam_errors.c b/source3/lib/pam_errors.c
index 212d3831fd..8a4c41d7df 100644
--- a/source3/lib/pam_errors.c
+++ b/source3/lib/pam_errors.c
@@ -71,6 +71,7 @@ static const struct {
{NT_STATUS_PASSWORD_MUST_CHANGE, PAM_NEW_AUTHTOK_REQD},
{NT_STATUS_ACCOUNT_LOCKED_OUT, PAM_MAXTRIES},
{NT_STATUS_NO_MEMORY, PAM_BUF_ERR},
+ {NT_STATUS_PASSWORD_RESTRICTION, PAM_PERM_DENIED},
{NT_STATUS_OK, PAM_SUCCESS}
};
diff --git a/source3/lib/pidfile.c b/source3/lib/pidfile.c
index b041eb7f1b..08e41083b5 100644
--- a/source3/lib/pidfile.c
+++ b/source3/lib/pidfile.c
@@ -32,7 +32,8 @@ pid_t pidfile_pid(const char *name)
{
int fd;
char pidstr[20];
- unsigned ret;
+ pid_t pid;
+ unsigned int ret;
pstring pidFile;
slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), name);
@@ -57,7 +58,8 @@ pid_t pidfile_pid(const char *name)
goto noproc;
}
- if (!process_exists_by_pid(ret)) {
+ pid = (pid_t)ret;
+ if (!process_exists_by_pid(pid)) {
goto noproc;
}
diff --git a/source3/lib/readline.c b/source3/lib/readline.c
index 78b99fd7fb..c1f1dc7f40 100644
--- a/source3/lib/readline.c
+++ b/source3/lib/readline.c
@@ -50,7 +50,7 @@
Display the prompt and wait for input. Call callback() regularly
****************************************************************************/
-static char *smb_readline_replacement(char *prompt, void (*callback)(void),
+static char *smb_readline_replacement(const char *prompt, void (*callback)(void),
char **(completion_fn)(const char *text, int start, int end))
{
fd_set fds;
@@ -82,7 +82,7 @@ static char *smb_readline_replacement(char *prompt, void (*callback)(void),
Display the prompt and wait for input. Call callback() regularly.
****************************************************************************/
-char *smb_readline(char *prompt, void (*callback)(void),
+char *smb_readline(const char *prompt, void (*callback)(void),
char **(completion_fn)(const char *text, int start, int end))
{
#if HAVE_LIBREADLINE
diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c
index ace0aee866..273bf0f0a3 100644
--- a/source3/lib/secdesc.c
+++ b/source3/lib/secdesc.c
@@ -23,6 +23,15 @@
#include "includes.h"
+/* Map generic permissions to file object specific permissions */
+
+struct generic_mapping file_generic_mapping = {
+ FILE_GENERIC_READ,
+ FILE_GENERIC_WRITE,
+ FILE_GENERIC_EXECUTE,
+ FILE_GENERIC_ALL
+};
+
/*******************************************************************
Works out the linearization size of a SEC_DESC.
********************************************************************/
@@ -520,3 +529,4 @@ void init_sec_access(SEC_ACCESS *t, uint32 mask)
t->mask = mask;
}
+
diff --git a/source3/lib/sharesec.c b/source3/lib/sharesec.c
new file mode 100644
index 0000000000..b98e304582
--- /dev/null
+++ b/source3/lib/sharesec.c
@@ -0,0 +1,308 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * SEC_DESC handling functions
+ * Copyright (C) Jeremy R. Allison 1995-2003.
+ *
+ * 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"
+
+/*******************************************************************
+ Create the share security tdb.
+ ********************************************************************/
+
+static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
+#define SHARE_DATABASE_VERSION_V1 1
+#define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
+
+/* Map generic permissions to file object specific permissions */
+
+static struct generic_mapping file_generic_mapping = {
+ FILE_GENERIC_READ,
+ FILE_GENERIC_WRITE,
+ FILE_GENERIC_EXECUTE,
+ FILE_GENERIC_ALL
+};
+
+
+BOOL share_info_db_init(void)
+{
+ const char *vstring = "INFO/version";
+ int32 vers_id;
+
+ if (share_tdb) {
+ return True;
+ }
+
+ share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ if (!share_tdb) {
+ DEBUG(0,("Failed to open share info database %s (%s)\n",
+ lock_path("share_info.tdb"), strerror(errno) ));
+ return False;
+ }
+
+ /* handle a Samba upgrade */
+ tdb_lock_bystring(share_tdb, vstring, 0);
+
+ /* Cope with byte-reversed older versions of the db. */
+ vers_id = tdb_fetch_int32(share_tdb, vstring);
+ if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
+ /* Written on a bigendian machine with old fetch_int code. Save as le. */
+ tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
+ vers_id = SHARE_DATABASE_VERSION_V2;
+ }
+
+ if (vers_id != SHARE_DATABASE_VERSION_V2) {
+ tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
+ tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
+ }
+ tdb_unlock_bystring(share_tdb, vstring);
+
+ return True;
+}
+
+/*******************************************************************
+ Fake up a Everyone, default access as a default.
+ def_access is a GENERIC_XXX access mode.
+ ********************************************************************/
+
+SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, size_t *psize, uint32 def_access)
+{
+ SEC_ACCESS sa;
+ SEC_ACE ace;
+ SEC_ACL *psa = NULL;
+ SEC_DESC *psd = NULL;
+ uint32 spec_access = def_access;
+
+ se_map_generic(&spec_access, &file_generic_mapping);
+
+ init_sec_access(&sa, def_access | spec_access );
+ init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
+
+ if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
+ psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, psize);
+ }
+
+ if (!psd) {
+ DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
+ return NULL;
+ }
+
+ return psd;
+}
+
+/*******************************************************************
+ Pull a security descriptor from the share tdb.
+ ********************************************************************/
+
+SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
+{
+ prs_struct ps;
+ fstring key;
+ SEC_DESC *psd = NULL;
+
+ if (!share_info_db_init()) {
+ return NULL;
+ }
+
+ *psize = 0;
+
+ /* Fetch security descriptor from tdb */
+
+ slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
+
+ if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
+ !sec_io_desc("get_share_security", &psd, &ps, 1)) {
+
+ DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
+
+ return get_share_security_default(ctx, psize, GENERIC_ALL_ACCESS);
+ }
+
+ if (psd)
+ *psize = sec_desc_size(psd);
+
+ prs_mem_free(&ps);
+ return psd;
+}
+
+/*******************************************************************
+ Store a security descriptor in the share db.
+ ********************************************************************/
+
+BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
+{
+ prs_struct ps;
+ TALLOC_CTX *mem_ctx = NULL;
+ fstring key;
+ BOOL ret = False;
+
+ if (!share_info_db_init()) {
+ return False;
+ }
+
+ mem_ctx = talloc_init("set_share_security");
+ if (mem_ctx == NULL)
+ return False;
+
+ prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
+
+ if (!sec_io_desc("share_security", &psd, &ps, 1))
+ goto out;
+
+ slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
+
+ if (tdb_prs_store(share_tdb, key, &ps)==0) {
+ ret = True;
+ DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
+ } else {
+ DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
+ }
+
+ /* Free malloc'ed memory */
+
+out:
+
+ prs_mem_free(&ps);
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return ret;
+}
+
+/*******************************************************************
+ Delete a security descriptor.
+********************************************************************/
+
+BOOL delete_share_security(int snum)
+{
+ TDB_DATA kbuf;
+ fstring key;
+
+ slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
+ kbuf.dptr = key;
+ kbuf.dsize = strlen(key)+1;
+
+ if (tdb_delete(share_tdb, kbuf) != 0) {
+ DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
+ lp_servicename(snum) ));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
+ Parse the contents of an acl string from a usershare file.
+***************************************************************************/
+
+BOOL parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, SEC_DESC **ppsd)
+{
+ size_t s_size = 0;
+ const char *pacl = acl_str;
+ int num_aces = 0;
+ SEC_ACE *ace_list = NULL;
+ SEC_ACL *psa = NULL;
+ SEC_DESC *psd = NULL;
+ size_t sd_size = 0;
+ int i;
+
+ *ppsd = NULL;
+
+ /* If the acl string is blank return "Everyone:R" */
+ if (!*acl_str) {
+ SEC_DESC *default_psd = get_share_security_default(ctx, &s_size, GENERIC_READ_ACCESS);
+ if (!default_psd) {
+ return False;
+ }
+ *ppsd = default_psd;
+ return True;
+ }
+
+ num_aces = 1;
+
+ /* Add the number of ',' characters to get the number of aces. */
+ num_aces += count_chars(pacl,',');
+
+ ace_list = TALLOC_ARRAY(ctx, SEC_ACE, num_aces);
+ if (!ace_list) {
+ return False;
+ }
+
+ for (i = 0; i < num_aces; i++) {
+ SEC_ACCESS sa;
+ uint32 g_access;
+ uint32 s_access;
+ DOM_SID sid;
+ fstring sidstr;
+ uint8 type = SEC_ACE_TYPE_ACCESS_ALLOWED;
+
+ if (!next_token(&pacl, sidstr, ":", sizeof(sidstr))) {
+ DEBUG(0,("parse_usershare_acl: malformed usershare acl looking "
+ "for ':' in string '%s'\n", pacl));
+ return False;
+ }
+
+ if (!string_to_sid(&sid, sidstr)) {
+ DEBUG(0,("parse_usershare_acl: failed to convert %s to sid.\n",
+ sidstr ));
+ return False;
+ }
+
+ switch (*pacl) {
+ case 'F': /* Full Control, ie. R+W */
+ case 'f': /* Full Control, ie. R+W */
+ s_access = g_access = GENERIC_ALL_ACCESS;
+ break;
+ case 'R': /* Read only. */
+ case 'r': /* Read only. */
+ s_access = g_access = GENERIC_READ_ACCESS;
+ break;
+ case 'D': /* Deny all to this SID. */
+ case 'd': /* Deny all to this SID. */
+ type = SEC_ACE_TYPE_ACCESS_DENIED;
+ s_access = g_access = GENERIC_ALL_ACCESS;
+ break;
+ default:
+ DEBUG(0,("parse_usershare_acl: unknown acl type at %s.\n",
+ pacl ));
+ return False;
+ }
+
+ pacl++;
+ if (*pacl && *pacl != ',') {
+ DEBUG(0,("parse_usershare_acl: bad acl string at %s.\n",
+ pacl ));
+ return False;
+ }
+ pacl++; /* Go past any ',' */
+
+ se_map_generic(&s_access, &file_generic_mapping);
+ init_sec_access(&sa, g_access | s_access );
+ init_sec_ace(&ace_list[i], &sid, type, sa, 0);
+ }
+
+ if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, num_aces, ace_list)) != NULL) {
+ psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, &sd_size);
+ }
+
+ if (!psd) {
+ DEBUG(0,("parse_usershare_acl: Failed to make SEC_DESC.\n"));
+ return False;
+ }
+
+ *ppsd = psd;
+ return True;
+}
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index 609816b877..c045be51c5 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -230,7 +230,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
Return the list of attribute names from a mapping table
**********************************************************************/
- const char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
+ const char** get_attr_list( TALLOC_CTX *mem_ctx, ATTRIB_MAP_ENTRY table[] )
{
const char **names;
int i = 0;
@@ -239,7 +239,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
i++;
i++;
- names = SMB_MALLOC_ARRAY( const char*, i );
+ names = TALLOC_ARRAY( mem_ctx, const char*, i );
if ( !names ) {
DEBUG(0,("get_attr_list: out of memory\n"));
return NULL;
@@ -247,7 +247,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
i = 0;
while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
- names[i] = SMB_STRDUP( table[i].name );
+ names[i] = talloc_strdup( names, table[i].name );
i++;
}
names[i] = NULL;
@@ -255,29 +255,6 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
return names;
}
-/*********************************************************************
- Cleanup
- ********************************************************************/
-
- void free_attr_list( const char **list )
-{
- int i = 0;
-
- if ( !list )
- return;
-
- while ( list[i] ) {
- /* SAFE_FREE generates a warning here that can't be gotten rid
- * of with CONST_DISCARD */
- if (list[i] != NULL) {
- free(CONST_DISCARD(char *, list[i]));
- }
- i+=1;
- }
-
- SAFE_FREE( list );
-}
-
/*******************************************************************
Search an attribute and return the first value found.
******************************************************************/
@@ -321,6 +298,88 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
sizeof(pstring));
}
+ char * smbldap_talloc_single_attribute(LDAP *ldap_struct, LDAPMessage *entry,
+ const char *attribute,
+ TALLOC_CTX *mem_ctx)
+{
+ char **values;
+ char *result;
+
+ if (attribute == NULL) {
+ return NULL;
+ }
+
+ values = ldap_get_values(ldap_struct, entry, attribute);
+
+ if (values == NULL) {
+ DEBUG(10, ("attribute %s does not exist\n", attribute));
+ return NULL;
+ }
+
+ if (ldap_count_values(values) != 1) {
+ DEBUG(10, ("attribute %s has %d values, expected only one\n",
+ attribute, ldap_count_values(values)));
+ ldap_value_free(values);
+ return NULL;
+ }
+
+ if (pull_utf8_talloc(mem_ctx, &result, values[0]) < 0) {
+ DEBUG(10, ("pull_utf8_talloc failed\n"));
+ ldap_value_free(values);
+ return NULL;
+ }
+
+ ldap_value_free(values);
+
+#ifdef DEBUG_PASSWORDS
+ DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
+ attribute, result));
+#endif
+ return result;
+}
+
+ static int ldapmsg_destructor(void *p) {
+ LDAPMessage **result = talloc_get_type_abort(p, LDAPMessage *);
+ ldap_msgfree(*result);
+ return 0;
+}
+
+ void talloc_autofree_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result)
+{
+ LDAPMessage **handle;
+
+ if (result == NULL) {
+ return;
+ }
+
+ handle = TALLOC_P(mem_ctx, LDAPMessage *);
+ SMB_ASSERT(handle != NULL);
+
+ *handle = result;
+ talloc_set_destructor(handle, ldapmsg_destructor);
+}
+
+ static int ldapmod_destructor(void *p) {
+ LDAPMod ***result = talloc_get_type_abort(p, LDAPMod **);
+ ldap_mods_free(*result, True);
+ return 0;
+}
+
+ void talloc_autofree_ldapmod(TALLOC_CTX *mem_ctx, LDAPMod **mod)
+{
+ LDAPMod ***handle;
+
+ if (mod == NULL) {
+ return;
+ }
+
+ handle = TALLOC_P(mem_ctx, LDAPMod **);
+ SMB_ASSERT(handle != NULL);
+
+ *handle = mod;
+ talloc_set_destructor(handle, ldapmod_destructor);
+}
+
/************************************************************************
Routine to manage the LDAPMod structure array
manage memory used by the array, by each struct, and values
@@ -1041,6 +1100,14 @@ static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
return True;
}
+ if (open_rc == LDAP_INSUFFICIENT_ACCESS) {
+ /* The fact that we are non-root or any other
+ * access-denied condition will not change in the next
+ * round of trying */
+ *rc = open_rc;
+ break;
+ }
+
if (got_alarm) {
*rc = LDAP_TIMEOUT;
break;
@@ -1123,12 +1190,22 @@ static int smbldap_search_ext(struct smbldap_state *ldap_state,
alarm(lp_ldap_timeout());
/* End setup timeout. */
- while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
rc = ldap_search_ext_s(ldap_state->ldap_struct, base, scope,
utf8_filter,
CONST_DISCARD(char **, attrs),
attrsonly, sctrls, cctrls, &timeout,
sizelimit, res);
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(10,("Failed search for base: %s, error: %s "
+ "(%s)\n", base, ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
+ SAFE_FREE(ld_error);
+ }
+ }
SAFE_FREE(utf8_filter);
@@ -1257,8 +1334,18 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
return LDAP_NO_MEMORY;
}
- while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(10,("Failed to modify dn: %s, error: %s "
+ "(%s)\n", dn, ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
+ SAFE_FREE(ld_error);
+ }
+ }
SAFE_FREE(utf8_dn);
return rc;
@@ -1279,8 +1366,18 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
return LDAP_NO_MEMORY;
}
- while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(10,("Failed to add dn: %s, error: %s "
+ "(%s)\n", dn, ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
+ SAFE_FREE(ld_error);
+ }
+ }
SAFE_FREE(utf8_dn);
return rc;
@@ -1301,8 +1398,18 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
return LDAP_NO_MEMORY;
}
- while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(10,("Failed to delete dn: %s, error: %s "
+ "(%s)\n", dn, ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
+ SAFE_FREE(ld_error);
+ }
+ }
SAFE_FREE(utf8_dn);
return rc;
@@ -1320,34 +1427,33 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state,
if (!ldap_state)
return (-1);
- while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid,
reqdata, serverctrls,
clientctrls, retoidp, retdatap);
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(10,("Extended operation failed with error: %s "
+ "(%s)\n", ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
+ SAFE_FREE(ld_error);
+ }
+ }
+
return rc;
}
/*******************************************************************
run the search by name.
******************************************************************/
-int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter,
- const char **search_attr, LDAPMessage ** result)
+int smbldap_search_suffix (struct smbldap_state *ldap_state,
+ const char *filter, const char **search_attr,
+ LDAPMessage ** result)
{
- int scope = LDAP_SCOPE_SUBTREE;
- int rc;
-
- rc = smbldap_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0,("smbldap_search_suffix: Problem during the LDAP search: %s (%s)\n",
- ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
- SAFE_FREE(ld_error);
- }
-
- return rc;
+ return smbldap_search(ldap_state, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE,
+ filter, search_attr, 0, result);
}
static void smbldap_idle_fn(void **data, time_t *interval, time_t now)
@@ -1442,6 +1548,25 @@ char *smbldap_get_dn(LDAP *ld, LDAPMessage *entry)
return unix_dn;
}
+ const char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld,
+ LDAPMessage *entry)
+{
+ char *utf8_dn, *unix_dn;
+
+ utf8_dn = ldap_get_dn(ld, entry);
+ if (!utf8_dn) {
+ DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
+ return NULL;
+ }
+ if (pull_utf8_talloc(mem_ctx, &unix_dn, utf8_dn) == (size_t)-1) {
+ DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 "
+ "[%s]\n", utf8_dn));
+ return NULL;
+ }
+ ldap_memfree(utf8_dn);
+ return unix_dn;
+}
+
/*******************************************************************
Check if root-dse has a certain Control or Extension
********************************************************************/
diff --git a/source3/lib/smbldap_util.c b/source3/lib/smbldap_util.c
index 4679b86487..7b4cf4d079 100644
--- a/source3/lib/smbldap_util.c
+++ b/source3/lib/smbldap_util.c
@@ -99,21 +99,17 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
pstring filter, dn;
LDAPMod **mods = NULL;
int rc;
- int ldap_op;
LDAPMessage *result = NULL;
int num_result;
const char **attr_list;
- uid_t u_low, u_high;
- gid_t g_low, g_high;
- uint32 rid_low, rid_high;
slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))",
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
domain_name, LDAP_OBJ_DOMINFO);
- attr_list = get_attr_list( dominfo_attr_list );
+ attr_list = get_attr_list( NULL, dominfo_attr_list );
rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result);
- free_attr_list( attr_list );
+ talloc_free( attr_list );
if (rc != LDAP_SUCCESS) {
return NT_STATUS_UNSUCCESSFUL;
@@ -122,80 +118,72 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
num_result = ldap_count_entries(ldap_state->ldap_struct, result);
if (num_result > 1) {
- DEBUG (0, ("More than domain with that name exists: bailing out!\n"));
+ DEBUG (0, ("More than domain with that name exists: bailing "
+ "out!\n"));
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
/* Check if we need to add an entry */
DEBUG(3,("Adding new domain\n"));
- ldap_op = LDAP_MOD_ADD;
- pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
- domain_name, lp_ldap_suffix());
+ pstr_sprintf(dn, "%s=%s,%s",
+ get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
+ domain_name, lp_ldap_suffix());
/* Free original search */
ldap_msgfree(result);
- /* make the changes - the entry *must* not already have samba attributes */
- smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
- domain_name);
+ /* make the changes - the entry *must* not already have samba
+ * attributes */
- /* If we don't have an entry, then ask secrets.tdb for what it thinks.
+ smbldap_set_mod(&mods, LDAP_MOD_ADD,
+ get_attr_key2string(dominfo_attr_list,
+ LDAP_ATTR_DOMAIN),
+ domain_name);
+
+ /* If we don't have an entry, then ask secrets.tdb for what it thinks.
It may choose to make it up */
sid_to_string(sid_string, get_global_sam_sid());
- smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), sid_string);
-
- slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string) - 1, "%i", algorithmic_rid_base());
- smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
+ smbldap_set_mod(&mods, LDAP_MOD_ADD,
+ get_attr_key2string(dominfo_attr_list,
+ LDAP_ATTR_DOM_SID),
+ sid_string);
+
+ slprintf(algorithmic_rid_base_string,
+ sizeof(algorithmic_rid_base_string) - 1, "%i",
+ algorithmic_rid_base());
+ smbldap_set_mod(&mods, LDAP_MOD_ADD,
+ get_attr_key2string(dominfo_attr_list,
+ LDAP_ATTR_ALGORITHMIC_RID_BASE),
algorithmic_rid_base_string);
smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
- /* add the sambaNext[User|Group]Rid attributes if the idmap ranges are set.
- TODO: fix all the places where the line between idmap and normal operations
- needed by smbd gets fuzzy --jerry 2003-08-11 */
+ /* add the sambaNextUserRid attributes. */
- if ( lp_idmap_uid(&u_low, &u_high) && lp_idmap_gid(&g_low, &g_high)
- && get_free_rid_range(&rid_low, &rid_high) )
{
+ uint32 rid = BASE_RID;
fstring rid_str;
- fstr_sprintf( rid_str, "%i", rid_high|USER_RID_TYPE );
+ fstr_sprintf( rid_str, "%i", rid );
DEBUG(10,("setting next available user rid [%s]\n", rid_str));
smbldap_set_mod(&mods, LDAP_MOD_ADD,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
- rid_str);
-
- fstr_sprintf( rid_str, "%i", rid_high|GROUP_RID_TYPE );
- DEBUG(10,("setting next available group rid [%s]\n", rid_str));
- smbldap_set_mod(&mods, LDAP_MOD_ADD,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
+ get_attr_key2string(dominfo_attr_list,
+ LDAP_ATTR_NEXT_USERRID),
rid_str);
-
}
- switch(ldap_op)
- {
- case LDAP_MOD_ADD:
- rc = smbldap_add(ldap_state, dn, mods);
- break;
- case LDAP_MOD_REPLACE:
- rc = smbldap_modify(ldap_state, dn, mods);
- break;
- default:
- DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
+ rc = smbldap_add(ldap_state, dn, mods);
+
if (rc!=LDAP_SUCCESS) {
char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(1,("failed to %s domain dn= %s with: %s\n\t%s\n",
- ldap_op == LDAP_MOD_ADD ? "add" : "modify",
- dn, ldap_err2string(rc),
- ld_error?ld_error:"unknown"));
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(1,("failed to add domain dn= %s with: %s\n\t%s\n",
+ dn, ldap_err2string(rc),
+ ld_error?ld_error:"unknown"));
SAFE_FREE(ld_error);
ldap_mods_free(mods, True);
@@ -227,9 +215,9 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
DEBUG(2, ("Searching for:[%s]\n", filter));
- attr_list = get_attr_list( dominfo_attr_list );
+ attr_list = get_attr_list( NULL, dominfo_attr_list );
rc = smbldap_search_suffix(ldap_state, filter, attr_list , result);
- free_attr_list( attr_list );
+ talloc_free( attr_list );
if (rc != LDAP_SUCCESS) {
DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc)));
diff --git a/source3/lib/system_smbd.c b/source3/lib/system_smbd.c
index 6c65f61ad7..1d4f88fbb9 100644
--- a/source3/lib/system_smbd.c
+++ b/source3/lib/system_smbd.c
@@ -28,47 +28,6 @@
#ifndef HAVE_GETGROUPLIST
-static int int_compare( int *a, int *b )
-{
- if ( *a == *b )
- return 0;
- else if ( *a < *b )
- return -1;
- else
- return 1;
-}
-
-void remove_duplicate_gids( int *num_groups, gid_t *groups )
-{
- int i;
- int count = *num_groups;
-
- if ( *num_groups <= 0 || !groups )
- return;
-
- DEBUG(8,("remove_duplicate_gids: Enter %d gids\n", *num_groups));
-
- qsort( groups, *num_groups, sizeof(gid_t), QSORT_CAST int_compare );
-
- for ( i=1; i<count; ) {
- if ( groups[i-1] == groups[i] ) {
- memmove( &groups[i-1], &groups[i], (count - i + 1)*sizeof(gid_t) );
-
- /* decrement the total number of groups and do not increment
- the loop counter */
- count--;
- continue;
- }
- i++;
- }
-
- *num_groups = count;
-
- DEBUG(8,("remove_duplicate_gids: Exit %d gids\n", *num_groups));
-
- return;
-}
-
/*
This is a *much* faster way of getting the list of groups for a user
without changing the current supplementary group list. The old
@@ -79,7 +38,8 @@ void remove_duplicate_gids( int *num_groups, gid_t *groups )
NOTE!! this function only works if it is called as root!
*/
-static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
+static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups,
+ int *grpcnt)
{
gid_t *gids_saved;
int ret, ngrp_saved, num_gids;
@@ -140,9 +100,6 @@ static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, in
}
groups[0] = gid;
*grpcnt = ret + 1;
-
- /* remove any duplicates gids in the list */
- remove_duplicate_gids( grpcnt, groups );
}
restore_re_gid();
@@ -169,11 +126,11 @@ static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grp
/* see if we should disable winbindd lookups for local users */
if (strchr(user, *lp_winbind_separator()) == NULL) {
if ( !winbind_off() )
- DEBUG(0,("sys_getgroup_list: Insufficient environment space for %s\n",
- WINBINDD_DONT_ENV));
+ DEBUG(0,("sys_getgroup_list: Insufficient environment space "
+ "for %s\n", WINBINDD_DONT_ENV));
else
- DEBUG(10,("sys_getgrouplist(): disabled winbindd for group lookup [user == %s]\n",
- user));
+ DEBUG(10,("sys_getgrouplist(): disabled winbindd for group "
+ "lookup [user == %s]\n", user));
}
#ifdef HAVE_GETGROUPLIST
@@ -190,8 +147,9 @@ static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grp
return retval;
}
-static BOOL getgroups_user(const char *user, gid_t primary_gid,
- gid_t **ret_groups, size_t *p_ngroups)
+BOOL getgroups_unix_user(TALLOC_CTX *mem_ctx, const char *user,
+ gid_t primary_gid,
+ gid_t **ret_groups, size_t *p_ngroups)
{
size_t ngrp;
int max_grp;
@@ -229,10 +187,11 @@ static BOOL getgroups_user(const char *user, gid_t primary_gid,
groups = NULL;
/* Add in primary group first */
- add_gid_to_array_unique(NULL, primary_gid, &groups, &ngrp);
+ add_gid_to_array_unique(mem_ctx, primary_gid, &groups, &ngrp);
for (i=0; i<max_grp; i++)
- add_gid_to_array_unique(NULL, temp_groups[i], &groups, &ngrp);
+ add_gid_to_array_unique(mem_ctx, temp_groups[i],
+ &groups, &ngrp);
*p_ngroups = ngrp;
*ret_groups = groups;
@@ -241,15 +200,22 @@ static BOOL getgroups_user(const char *user, gid_t primary_gid,
}
NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods,
- const char *username,
- gid_t primary_gid,
+ TALLOC_CTX *mem_ctx,
+ SAM_ACCOUNT *user,
DOM_SID **pp_sids,
gid_t **pp_gids,
size_t *p_num_groups)
{
size_t i;
+ gid_t gid;
+
+ if (!sid_to_gid(pdb_get_group_sid(user), &gid)) {
+ DEBUG(10, ("sid_to_gid failed\n"));
+ return NT_STATUS_NO_SUCH_USER;
+ }
- if (!getgroups_user(username, primary_gid, pp_gids, p_num_groups)) {
+ if (!getgroups_unix_user(mem_ctx, pdb_get_username(user), gid,
+ pp_gids, p_num_groups)) {
return NT_STATUS_NO_SUCH_USER;
}
@@ -257,22 +223,15 @@ NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods,
smb_panic("primary group missing");
}
- *pp_sids = SMB_MALLOC_ARRAY(DOM_SID, *p_num_groups);
+ *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups);
if (*pp_sids == NULL) {
- SAFE_FREE(pp_gids);
+ talloc_free(*pp_gids);
return NT_STATUS_NO_MEMORY;
}
for (i=0; i<*p_num_groups; i++) {
- if (!NT_STATUS_IS_OK(gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]))) {
- DEBUG(1, ("get_user_groups: failed to convert "
- "gid %ld to a sid!\n",
- (long int)(*pp_gids)[i+1]));
- SAFE_FREE(*pp_sids);
- SAFE_FREE(*pp_gids);
- return NT_STATUS_NO_SUCH_USER;
- }
+ gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]);
}
return NT_STATUS_OK;
diff --git a/source3/lib/username.c b/source3/lib/username.c
index 7d66b320ad..c04dfd05da 100644
--- a/source3/lib/username.c
+++ b/source3/lib/username.c
@@ -22,8 +22,12 @@
#include "includes.h"
/* internal functions */
-static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (const char *), int N);
-static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (const char *), int N);
+static struct passwd *uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
+ struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
+ int N);
+static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx, int offset,
+ struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
+ int N);
/*****************************************************************
Check if a user or group name is local (this is a *local* name for
@@ -108,7 +112,7 @@ BOOL map_username(fstring user)
}
numlines = 0;
- qlines = fd_lines_load(fd, &numlines);
+ qlines = fd_lines_load(fd, &numlines,0);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
close(fd);
@@ -180,7 +184,8 @@ BOOL map_username(fstring user)
return False;
}
- if (strchr_m(dosname,'*') || user_in_list(user, (const char **)dosuserlist, NULL, 0)) {
+ if (strchr_m(dosname,'*') ||
+ user_in_list(user, (const char **)dosuserlist)) {
DEBUG(3,("Mapped user %s to %s\n",user,unixname));
mapped_user = True;
fstrcpy( last_from,user );
@@ -218,7 +223,8 @@ BOOL map_username(fstring user)
static struct passwd *Get_Pwnam_ret = NULL;
-static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
+static struct passwd *Get_Pwnam_internals(TALLOC_CTX *mem_ctx,
+ const char *user, char *user2)
{
struct passwd *ret = NULL;
@@ -232,7 +238,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
common case on UNIX systems */
strlower_m(user2);
DEBUG(5,("Trying _Get_Pwnam(), username as lowercase is %s\n",user2));
- ret = getpwnam_alloc(user2);
+ ret = getpwnam_alloc(mem_ctx, user2);
if(ret)
goto done;
@@ -240,7 +246,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
if(strcmp(user, user2) != 0) {
DEBUG(5,("Trying _Get_Pwnam(), username as given is %s\n",
user));
- ret = getpwnam_alloc(user);
+ ret = getpwnam_alloc(mem_ctx, user);
if(ret)
goto done;
}
@@ -250,7 +256,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
if(strcmp(user, user2) != 0) {
DEBUG(5,("Trying _Get_Pwnam(), username as uppercase is %s\n",
user2));
- ret = getpwnam_alloc(user2);
+ ret = getpwnam_alloc(mem_ctx, user2);
if(ret)
goto done;
}
@@ -259,7 +265,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
strlower_m(user2);
DEBUG(5,("Checking combinations of %d uppercase letters in %s\n",
lp_usernamelevel(), user2));
- ret = uname_string_combinations(user2, getpwnam_alloc,
+ ret = uname_string_combinations(user2, mem_ctx, getpwnam_alloc,
lp_usernamelevel());
done:
@@ -275,7 +281,7 @@ done:
This will return an allocated structure
****************************************************************************/
-struct passwd *Get_Pwnam_alloc(const char *user)
+struct passwd *Get_Pwnam_alloc(TALLOC_CTX *mem_ctx, const char *user)
{
fstring user2;
struct passwd *ret;
@@ -289,7 +295,7 @@ struct passwd *Get_Pwnam_alloc(const char *user)
DEBUG(5,("Finding user %s\n", user));
- ret = Get_Pwnam_internals(user, user2);
+ ret = Get_Pwnam_internals(mem_ctx, user, user2);
return ret;
}
@@ -303,7 +309,7 @@ struct passwd *Get_Pwnam(const char *user)
{
struct passwd *ret;
- ret = Get_Pwnam_alloc(user);
+ ret = Get_Pwnam_alloc(NULL, user);
/* This call used to just return the 'passwd' static buffer.
This could then have accidental reuse implications, so
@@ -320,7 +326,7 @@ struct passwd *Get_Pwnam(const char *user)
*/
if (Get_Pwnam_ret) {
- passwd_free(&Get_Pwnam_ret);
+ talloc_free(Get_Pwnam_ret);
}
Get_Pwnam_ret = ret;
@@ -333,7 +339,7 @@ struct passwd *Get_Pwnam(const char *user)
try lower case.
****************************************************************************/
-static BOOL user_in_netgroup_list(const char *user, const char *ngname)
+BOOL user_in_netgroup(const char *user, const char *ngname)
{
#ifdef HAVE_NETGROUP
static char *mydomain = NULL;
@@ -351,7 +357,7 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
user, mydomain, ngname));
if (innetgr(ngname, NULL, user, mydomain)) {
- DEBUG(5,("user_in_netgroup_list: Found\n"));
+ DEBUG(5,("user_in_netgroup: Found\n"));
return (True);
} else {
@@ -367,7 +373,7 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
lowercase_user, mydomain, ngname));
if (innetgr(ngname, NULL, lowercase_user, mydomain)) {
- DEBUG(5,("user_in_netgroup_list: Found\n"));
+ DEBUG(5,("user_in_netgroup: Found\n"));
return (True);
}
}
@@ -379,8 +385,8 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
Check if a user is in a winbind group.
****************************************************************************/
-static BOOL user_in_winbind_group_list(const char *user, const char *gname,
- BOOL *winbind_answered)
+static BOOL user_in_winbind_group(const char *user, const char *gname,
+ BOOL *winbind_answered)
{
int i;
gid_t gid, gid_low, gid_high;
@@ -392,7 +398,7 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname,
*winbind_answered = False;
if ((gid = nametogid(gname)) == (gid_t)-1) {
- DEBUG(0,("user_in_winbind_group_list: nametogid for group %s "
+ DEBUG(0,("user_in_winbind_group: nametogid for group %s "
"failed.\n", gname ));
goto err;
}
@@ -439,11 +445,11 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname,
}
else
- DEBUG(10,("user_in_winbind_group_list: using cached user "
+ DEBUG(10,("user_in_winbind_group: using cached user "
"groups for [%s]\n", user));
if ( DEBUGLEVEL >= 10 ) {
- DEBUG(10,("user_in_winbind_group_list: using groups -- "));
+ DEBUG(10,("user_in_winbind_group: using groups -- "));
for ( i=0; i<num_groups; i++ )
DEBUGADD(10,("%lu ", (unsigned long)groups[i]));
DEBUGADD(10,("\n"));
@@ -477,13 +483,13 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname,
Check if a user is in a UNIX group.
****************************************************************************/
-BOOL user_in_unix_group_list(const char *user,const char *gname)
+BOOL user_in_unix_group(const char *user,const char *gname)
{
struct passwd *pass = Get_Pwnam(user);
struct sys_userlist *user_list;
struct sys_userlist *member;
- DEBUG(10,("user_in_unix_group_list: checking user %s in group %s\n",
+ DEBUG(10,("user_in_unix_group: checking user %s in group %s\n",
user, gname));
/*
@@ -493,7 +499,7 @@ BOOL user_in_unix_group_list(const char *user,const char *gname)
if (pass) {
if (strequal(gname,gidtoname(pass->pw_gid))) {
- DEBUG(10,("user_in_unix_group_list: group %s is "
+ DEBUG(10,("user_in_unix_group: group %s is "
"primary group.\n", gname ));
return True;
}
@@ -501,13 +507,13 @@ BOOL user_in_unix_group_list(const char *user,const char *gname)
user_list = get_users_in_group(gname);
if (user_list == NULL) {
- DEBUG(10,("user_in_unix_group_list: no such group %s\n",
+ DEBUG(10,("user_in_unix_group: no such group %s\n",
gname ));
return False;
}
for (member = user_list; member; member = member->next) {
- DEBUG(10,("user_in_unix_group_list: checking user %s against "
+ DEBUG(10,("user_in_unix_group: checking user %s against "
"member %s\n", user, member->unix_name ));
if (strequal(member->unix_name,user)) {
free_userlist(user_list);
@@ -523,35 +529,17 @@ BOOL user_in_unix_group_list(const char *user,const char *gname)
Check if a user is in a group list. Ask winbind first, then use UNIX.
****************************************************************************/
-BOOL user_in_group_list(const char *user, const char *gname, gid_t *groups,
- size_t n_groups)
+BOOL user_in_group(const char *user, const char *gname)
{
BOOL winbind_answered = False;
BOOL ret;
- gid_t gid;
- unsigned i;
- gid = nametogid(gname);
- if (gid == (gid_t)-1)
- return False;
-
- if (groups && n_groups > 0) {
- for (i=0; i < n_groups; i++) {
- if (groups[i] == gid) {
- return True;
- }
- }
- return False;
- }
-
- /* fallback if we don't yet have the group list */
-
- ret = user_in_winbind_group_list(user, gname, &winbind_answered);
+ ret = user_in_winbind_group(user, gname, &winbind_answered);
if (!winbind_answered)
- ret = user_in_unix_group_list(user, gname);
+ ret = user_in_unix_group(user, gname);
if (ret)
- DEBUG(10,("user_in_group_list: user |%s| is in group |%s|\n",
+ DEBUG(10,("user_in_group: user |%s| is in group |%s|\n",
user, gname));
return ret;
}
@@ -561,8 +549,7 @@ BOOL user_in_group_list(const char *user, const char *gname, gid_t *groups,
and netgroup lists.
****************************************************************************/
-BOOL user_in_list(const char *user,const char **list, gid_t *groups,
- size_t n_groups)
+BOOL user_in_list(const char *user,const char **list)
{
if (!list || !*list)
return False;
@@ -590,10 +577,9 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
* Old behaviour. Check netgroup list
* followed by UNIX list.
*/
- if(user_in_netgroup_list(user, *list +1))
+ if(user_in_netgroup(user, *list +1))
return True;
- if(user_in_group_list(user, *list +1, groups,
- n_groups))
+ if(user_in_group(user, *list +1))
return True;
} else if (**list == '+') {
@@ -601,10 +587,9 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
/*
* Search UNIX list followed by netgroup.
*/
- if(user_in_group_list(user, *list +2, groups,
- n_groups))
+ if(user_in_group(user, *list +2))
return True;
- if(user_in_netgroup_list(user, *list +2))
+ if(user_in_netgroup(user, *list +2))
return True;
} else {
@@ -613,8 +598,7 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
* Just search UNIX list.
*/
- if(user_in_group_list(user, *list +1, groups,
- n_groups))
+ if(user_in_group(user, *list +1))
return True;
}
@@ -624,16 +608,15 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
/*
* Search netgroup list followed by UNIX list.
*/
- if(user_in_netgroup_list(user, *list +2))
+ if(user_in_netgroup(user, *list +2))
return True;
- if(user_in_group_list(user, *list +2, groups,
- n_groups))
+ if(user_in_group(user, *list +2))
return True;
} else {
/*
* Just search netgroup list.
*/
- if(user_in_netgroup_list(user, *list +1))
+ if(user_in_netgroup(user, *list +1))
return True;
}
} else if (!name_is_local(*list)) {
@@ -676,7 +659,7 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
/* Check if user name is in the
* Windows group */
- ret = user_in_winbind_group_list(
+ ret = user_in_winbind_group(
user, *list,
&winbind_answered);
@@ -705,21 +688,24 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
it assumes the string starts lowercased
****************************************************************************/
-static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(const char *),int N)
+static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx,
+ int offset,
+ struct passwd *(*fn)(TALLOC_CTX *mem_ctx, const char *),
+ int N)
{
ssize_t len = (ssize_t)strlen(s);
int i;
struct passwd *ret;
if (N <= 0 || offset >= len)
- return(fn(s));
+ return(fn(mem_ctx, s));
for (i=offset;i<(len-(N-1));i++) {
char c = s[i];
if (!islower_ascii((int)c))
continue;
s[i] = toupper_ascii(c);
- ret = uname_string_combinations2(s,i+1,fn,N-1);
+ ret = uname_string_combinations2(s, mem_ctx, i+1, fn, N-1);
if(ret)
return(ret);
s[i] = c;
@@ -735,13 +721,15 @@ static struct passwd *uname_string_combinations2(char *s,int offset,struct passw
it assumes the string starts lowercased
****************************************************************************/
-static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(const char *),int N)
+static struct passwd * uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
+ struct passwd * (*fn)(TALLOC_CTX *mem_ctx, const char *),
+ int N)
{
int n;
struct passwd *ret;
for (n=1;n<=N;n++) {
- ret = uname_string_combinations2(s,0,fn,n);
+ ret = uname_string_combinations2(s,mem_ctx,0,fn,n);
if(ret)
return(ret);
}
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 38878befc7..dc57839df3 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -1427,10 +1427,10 @@ const char *uidtoname(uid_t uid)
static fstring name;
struct passwd *pass;
- pass = getpwuid_alloc(uid);
+ pass = getpwuid_alloc(NULL, uid);
if (pass) {
fstrcpy(name, pass->pw_name);
- passwd_free(&pass);
+ talloc_free(pass);
} else {
slprintf(name, sizeof(name) - 1, "%ld",(long int)uid);
}
@@ -1464,10 +1464,10 @@ uid_t nametouid(const char *name)
char *p;
uid_t u;
- pass = getpwnam_alloc(name);
+ pass = getpwnam_alloc(NULL, name);
if (pass) {
u = pass->pw_uid;
- passwd_free(&pass);
+ talloc_free(pass);
return u;
}
diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c
index 407a8b24fc..53a9bc9b41 100644
--- a/source3/lib/util_file.c
+++ b/source3/lib/util_file.c
@@ -386,30 +386,37 @@ char *file_pload(char *syscmd, size_t *size)
/****************************************************************************
Load a file into memory from a fd.
+ Truncate at maxsize. If maxsize == 0 - no limit.
****************************************************************************/
-char *fd_load(int fd, size_t *size)
+char *fd_load(int fd, size_t *psize, size_t maxsize)
{
SMB_STRUCT_STAT sbuf;
+ size_t size;
char *p;
if (sys_fstat(fd, &sbuf) != 0) {
return NULL;
}
- p = (char *)SMB_MALLOC(sbuf.st_size+1);
+ size = sbuf.st_size;
+ if (maxsize) {
+ size = MIN(size, maxsize);
+ }
+
+ p = (char *)SMB_MALLOC(size+1);
if (!p) {
return NULL;
}
- if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
+ if (read(fd, p, size) != size) {
SAFE_FREE(p);
return NULL;
}
- p[sbuf.st_size] = 0;
+ p[size] = 0;
- if (size) {
- *size = sbuf.st_size;
+ if (psize) {
+ *psize = size;
}
return p;
@@ -419,7 +426,7 @@ char *fd_load(int fd, size_t *size)
Load a file into memory.
****************************************************************************/
-char *file_load(const char *fname, size_t *size)
+char *file_load(const char *fname, size_t *size, size_t maxsize)
{
int fd;
char *p;
@@ -433,7 +440,7 @@ char *file_load(const char *fname, size_t *size)
return NULL;
}
- p = fd_load(fd, size);
+ p = fd_load(fd, size, maxsize);
close(fd);
return p;
}
@@ -461,7 +468,7 @@ void *map_file(char *fname, size_t size)
}
#endif
if (!p) {
- p = file_load(fname, &s2);
+ p = file_load(fname, &s2, 0);
if (!p) {
return NULL;
}
@@ -522,12 +529,12 @@ static char **file_lines_parse(char *p, size_t size, int *numlines)
must be freed with file_lines_free().
****************************************************************************/
-char **file_lines_load(const char *fname, int *numlines)
+char **file_lines_load(const char *fname, int *numlines, size_t maxsize)
{
char *p;
size_t size = 0;
- p = file_load(fname, &size);
+ p = file_load(fname, &size, maxsize);
if (!p) {
return NULL;
}
@@ -541,12 +548,12 @@ char **file_lines_load(const char *fname, int *numlines)
the list.
****************************************************************************/
-char **fd_lines_load(int fd, int *numlines)
+char **fd_lines_load(int fd, int *numlines, size_t maxsize)
{
char *p;
size_t size;
- p = fd_load(fd, &size);
+ p = fd_load(fd, &size, maxsize);
if (!p) {
return NULL;
}
diff --git a/source3/lib/util_pw.c b/source3/lib/util_pw.c
index 13349bad34..e026affb44 100644
--- a/source3/lib/util_pw.c
+++ b/source3/lib/util_pw.c
@@ -22,69 +22,45 @@
#include "includes.h"
-static struct passwd *alloc_copy_passwd(const struct passwd *from)
+static struct passwd *talloc_copy_passwd(TALLOC_CTX *mem_ctx,
+ const struct passwd *from)
{
- struct passwd *ret = SMB_XMALLOC_P(struct passwd);
- ZERO_STRUCTP(ret);
- ret->pw_name = smb_xstrdup(from->pw_name);
- ret->pw_passwd = smb_xstrdup(from->pw_passwd);
+ struct passwd *ret = TALLOC_P(mem_ctx, struct passwd);
+ ret->pw_name = talloc_strdup(ret, from->pw_name);
+ ret->pw_passwd = talloc_strdup(ret, from->pw_passwd);
ret->pw_uid = from->pw_uid;
ret->pw_gid = from->pw_gid;
- ret->pw_gecos = smb_xstrdup(from->pw_gecos);
- ret->pw_dir = smb_xstrdup(from->pw_dir);
- ret->pw_shell = smb_xstrdup(from->pw_shell);
+ ret->pw_gecos = talloc_strdup(ret, from->pw_gecos);
+ ret->pw_dir = talloc_strdup(ret, from->pw_dir);
+ ret->pw_shell = talloc_strdup(ret, from->pw_shell);
return ret;
}
-void passwd_free (struct passwd **buf)
-{
- if (!*buf) {
- DEBUG(0, ("attempted double-free of allocated passwd\n"));
- return;
- }
-
- SAFE_FREE((*buf)->pw_name);
- SAFE_FREE((*buf)->pw_passwd);
- SAFE_FREE((*buf)->pw_gecos);
- SAFE_FREE((*buf)->pw_dir);
- SAFE_FREE((*buf)->pw_shell);
-
- SAFE_FREE(*buf);
-}
-
#define PWNAMCACHE_SIZE 4
-static struct passwd *pwnam_cache[PWNAMCACHE_SIZE];
-static BOOL pwnam_cache_initialized = False;
+static struct passwd **pwnam_cache = NULL;
static void init_pwnam_cache(void)
{
- int i;
-
- if (pwnam_cache_initialized)
+ if (pwnam_cache != NULL)
return;
- for (i=0; i<PWNAMCACHE_SIZE; i++)
- pwnam_cache[i] = NULL;
+ pwnam_cache = TALLOC_ZERO_ARRAY(NULL, struct passwd *,
+ PWNAMCACHE_SIZE);
+ if (pwnam_cache == NULL) {
+ smb_panic("Could not init pwnam_cache\n");
+ }
- pwnam_cache_initialized = True;
return;
}
void flush_pwnam_cache(void)
{
- int i;
-
+ talloc_free(pwnam_cache);
+ pwnam_cache = NULL;
init_pwnam_cache();
-
- for (i=0; i<PWNAMCACHE_SIZE; i++) {
- if (pwnam_cache[i] == NULL)
- continue;
-
- passwd_free(&pwnam_cache[i]);
- }
}
-struct passwd *getpwnam_alloc(const char *name)
+struct passwd *getpwnam_alloc(TALLOC_CTX *mem_ctx, const char *name)
{
int i;
@@ -96,7 +72,7 @@ struct passwd *getpwnam_alloc(const char *name)
if ((pwnam_cache[i] != NULL) &&
(strcmp(name, pwnam_cache[i]->pw_name) == 0)) {
DEBUG(10, ("Got %s from pwnam_cache\n", name));
- return alloc_copy_passwd(pwnam_cache[i]);
+ return talloc_reference(mem_ctx, pwnam_cache[i]);
}
}
@@ -119,15 +95,20 @@ struct passwd *getpwnam_alloc(const char *name)
if (i == PWNAMCACHE_SIZE)
i = rand() % PWNAMCACHE_SIZE;
- if (pwnam_cache[i] != NULL)
- passwd_free(&pwnam_cache[i]);
+ if (pwnam_cache[i] != NULL) {
+ talloc_free(pwnam_cache[i]);
+ }
- pwnam_cache[i] = alloc_copy_passwd(temp);
+ pwnam_cache[i] = talloc_copy_passwd(pwnam_cache, temp);
+
+ if (mem_ctx != NULL) {
+ return talloc_reference(mem_ctx, pwnam_cache[i]);
+ }
- return alloc_copy_passwd(temp);
+ return talloc_copy_passwd(NULL, pwnam_cache[i]);
}
-struct passwd *getpwuid_alloc(uid_t uid)
+struct passwd *getpwuid_alloc(TALLOC_CTX *mem_ctx, uid_t uid)
{
struct passwd *temp;
@@ -142,5 +123,5 @@ struct passwd *getpwuid_alloc(uid_t uid)
return NULL;
}
- return alloc_copy_passwd(temp);
+ return talloc_copy_passwd(mem_ctx, temp);
}
diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c
index e2b2ebf28c..c7f9dc2fdb 100644
--- a/source3/lib/util_sid.c
+++ b/source3/lib/util_sid.c
@@ -75,6 +75,11 @@ const DOM_SID global_sid_Builtin_Backup_Operators = /* Builtin backup operators
const DOM_SID global_sid_Builtin_Replicator = /* Builtin replicator */
{ 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Unix_Users = /* Unmapped Unix users */
+{ 1, 1, {0,0,0,0,0,22}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Unix_Groups = /* Unmapped Unix groups */
+{ 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
/* Unused, left here for documentary purposes */
#if 0
#define SECURITY_NULL_SID_AUTHORITY 0
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 0b02487f77..85b5cfc90a 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -1667,7 +1667,7 @@ int fstr_sprintf(fstring s, const char *fmt, ...)
#define S_LIST_ABS 16 /* List Allocation Block Size */
-char **str_list_make(const char *string, const char *sep)
+static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
{
char **list, **rlist;
const char *str;
@@ -1677,7 +1677,11 @@ char **str_list_make(const char *string, const char *sep)
if (!string || !*string)
return NULL;
- s = SMB_STRDUP(string);
+ if (mem_ctx) {
+ s = talloc_strdup(mem_ctx, string);
+ } else {
+ s = SMB_STRDUP(string);
+ }
if (!s) {
DEBUG(0,("str_list_make: Unable to allocate memory"));
return NULL;
@@ -1691,32 +1695,64 @@ char **str_list_make(const char *string, const char *sep)
while (next_token(&str, tok, sep, sizeof(tok))) {
if (num == lsize) {
lsize += S_LIST_ABS;
- rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
+ if (mem_ctx) {
+ rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
+ } else {
+ rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
+ }
if (!rlist) {
DEBUG(0,("str_list_make: Unable to allocate memory"));
str_list_free(&list);
- SAFE_FREE(s);
+ if (mem_ctx) {
+ talloc_free(s);
+ } else {
+ SAFE_FREE(s);
+ }
return NULL;
} else
list = rlist;
memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
}
+
+ if (mem_ctx) {
+ list[num] = talloc_strdup(mem_ctx, tok);
+ } else {
+ list[num] = SMB_STRDUP(tok);
+ }
- list[num] = SMB_STRDUP(tok);
if (!list[num]) {
DEBUG(0,("str_list_make: Unable to allocate memory"));
str_list_free(&list);
- SAFE_FREE(s);
+ if (mem_ctx) {
+ talloc_free(s);
+ } else {
+ SAFE_FREE(s);
+ }
return NULL;
}
num++;
}
-
- SAFE_FREE(s);
+
+ if (mem_ctx) {
+ talloc_free(s);
+ } else {
+ SAFE_FREE(s);
+ }
+
return list;
}
+char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
+{
+ return str_list_make_internal(mem_ctx, string, sep);
+}
+
+char **str_list_make(const char *string, const char *sep)
+{
+ return str_list_make_internal(NULL, string, sep);
+}
+
BOOL str_list_copy(char ***dest, const char **src)
{
char **list, **rlist;
@@ -1778,16 +1814,35 @@ BOOL str_list_compare(char **list1, char **list2)
return True;
}
-void str_list_free(char ***list)
+static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
{
char **tlist;
if (!list || !*list)
return;
tlist = *list;
- for(; *tlist; tlist++)
- SAFE_FREE(*tlist);
- SAFE_FREE(*list);
+ for(; *tlist; tlist++) {
+ if (mem_ctx) {
+ talloc_free(*tlist);
+ } else {
+ SAFE_FREE(*tlist);
+ }
+ }
+ if (mem_ctx) {
+ talloc_free(*tlist);
+ } else {
+ SAFE_FREE(*list);
+ }
+}
+
+void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
+{
+ str_list_free_internal(mem_ctx, list);
+}
+
+void str_list_free(char ***list)
+{
+ str_list_free_internal(NULL, list);
}
/******************************************************************************
@@ -2317,3 +2372,23 @@ char *sstring_sub(const char *src, char front, char back)
temp3[len-1] = '\0';
return temp3;
}
+
+/********************************************************************
+ Check a string for any occurrences of a specified list of invalid
+ characters.
+********************************************************************/
+
+BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
+{
+ int i;
+
+ for ( i=0; i<max_len && name[i]; i++ ) {
+ /* fail if strchr_m() finds one of the invalid characters */
+ if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
+ return False;
+ }
+ }
+
+ return True;
+}
+
diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c
index 880416a549..bc90314fce 100644
--- a/source3/lib/util_unistr.c
+++ b/source3/lib/util_unistr.c
@@ -291,24 +291,18 @@ int rpcstr_pull_unistr2_fstring(char *dest, UNISTR2 *src)
* have been to manually talloc_strdup them in rpc_client/cli_netlogon.c.
*/
-size_t rpcstr_pull_unistr2_talloc(TALLOC_CTX *mem_ctx, char **dest,
- UNISTR2 *src)
+char *rpcstr_pull_unistr2_talloc(TALLOC_CTX *mem_ctx, UNISTR2 *src)
{
pstring tmp;
size_t result;
result = pull_ucs2(NULL, tmp, src->buffer, sizeof(tmp),
src->uni_str_len * 2, 0);
- if (result < 0) {
- return result;
- }
-
- *dest = talloc_strdup(mem_ctx, tmp);
- if (*dest == NULL) {
- return -1;
+ if (result == (size_t)-1) {
+ return NULL;
}
- return result;
+ return talloc_strdup(mem_ctx, tmp);
}
/* Converts a string from internal samba format to unicode