summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/include/includes.h4
-rw-r--r--source4/lib/basic.mk2
-rw-r--r--source4/lib/username.c83
-rw-r--r--source4/modules/developer.c132
-rw-r--r--source4/modules/mysql.c1043
-rw-r--r--source4/modules/vfs_audit.c278
-rw-r--r--source4/modules/vfs_extd_audit.c319
-rw-r--r--source4/modules/vfs_fake_perms.c471
-rw-r--r--source4/modules/vfs_netatalk.c429
-rw-r--r--source4/modules/vfs_recycle.c648
-rw-r--r--source4/modules/xml.c575
-rw-r--r--source4/nmbd/asyncdns.c349
-rw-r--r--source4/nmbd/nmbd.c778
-rw-r--r--source4/nmbd/nmbd_become_dmb.c396
-rw-r--r--source4/nmbd/nmbd_become_lmb.c605
-rw-r--r--source4/nmbd/nmbd_browserdb.c182
-rw-r--r--source4/nmbd/nmbd_browsesync.c699
-rw-r--r--source4/nmbd/nmbd_elections.c403
-rw-r--r--source4/nmbd/nmbd_incomingdgrams.c858
-rw-r--r--source4/nmbd/nmbd_incomingrequests.c596
-rw-r--r--source4/nmbd/nmbd_lmhosts.c104
-rw-r--r--source4/nmbd/nmbd_logonnames.c172
-rw-r--r--source4/nmbd/nmbd_mynames.c228
-rw-r--r--source4/nmbd/nmbd_namelistdb.c624
-rw-r--r--source4/nmbd/nmbd_namequery.c304
-rw-r--r--source4/nmbd/nmbd_nameregister.c522
-rw-r--r--source4/nmbd/nmbd_namerelease.c222
-rw-r--r--source4/nmbd/nmbd_nodestatus.c94
-rw-r--r--source4/nmbd/nmbd_packets.c2013
-rw-r--r--source4/nmbd/nmbd_processlogon.c480
-rw-r--r--source4/nmbd/nmbd_responserecordsdb.c264
-rw-r--r--source4/nmbd/nmbd_sendannounce.c607
-rw-r--r--source4/nmbd/nmbd_serverlistdb.c448
-rw-r--r--source4/nmbd/nmbd_subnetdb.c361
-rw-r--r--source4/nmbd/nmbd_synclists.c300
-rw-r--r--source4/nmbd/nmbd_winsproxy.c221
-rw-r--r--source4/nmbd/nmbd_winsserver.c2032
-rw-r--r--source4/nmbd/nmbd_workgroupdb.c342
-rw-r--r--source4/nsswitch/README13
-rw-r--r--source4/nsswitch/config.m4105
-rw-r--r--source4/nsswitch/hp_nss_common.h51
-rw-r--r--source4/nsswitch/hp_nss_dbdefs.h105
-rw-r--r--source4/nsswitch/nss.h104
-rw-r--r--source4/nsswitch/pam_winbind.c754
-rw-r--r--source4/nsswitch/pam_winbind.h93
-rw-r--r--source4/nsswitch/wb_client.c104
-rw-r--r--source4/nsswitch/wb_common.c433
-rw-r--r--source4/nsswitch/wbinfo.c891
-rw-r--r--source4/nsswitch/winbind_client.h16
-rw-r--r--source4/nsswitch/winbind_nss.c1341
-rw-r--r--source4/nsswitch/winbind_nss_config.h165
-rw-r--r--source4/nsswitch/winbind_nss_solaris.c301
-rw-r--r--source4/nsswitch/winbindd.c951
-rw-r--r--source4/nsswitch/winbindd.h230
-rw-r--r--source4/nsswitch/winbindd_ads.c837
-rw-r--r--source4/nsswitch/winbindd_cache.c1016
-rw-r--r--source4/nsswitch/winbindd_cm.c954
-rw-r--r--source4/nsswitch/winbindd_dual.c210
-rw-r--r--source4/nsswitch/winbindd_group.c896
-rw-r--r--source4/nsswitch/winbindd_idmap.c196
-rw-r--r--source4/nsswitch/winbindd_idmap_tdb.c441
-rw-r--r--source4/nsswitch/winbindd_misc.c235
-rw-r--r--source4/nsswitch/winbindd_nss.h242
-rw-r--r--source4/nsswitch/winbindd_pam.c368
-rw-r--r--source4/nsswitch/winbindd_rpc.c776
-rw-r--r--source4/nsswitch/winbindd_sid.c235
-rw-r--r--source4/nsswitch/winbindd_user.c607
-rw-r--r--source4/nsswitch/winbindd_util.c553
-rw-r--r--source4/nsswitch/winbindd_wins.c210
-rw-r--r--source4/nsswitch/wins.c322
-rw-r--r--source4/printing/config.m416
-rw-r--r--source4/printing/load.c73
-rw-r--r--source4/printing/lpq_parse.c1099
-rw-r--r--source4/printing/notify.c526
-rw-r--r--source4/printing/pcap.c413
-rw-r--r--source4/printing/print_cups.c1293
-rw-r--r--source4/printing/print_generic.c245
-rw-r--r--source4/printing/print_svid.c144
-rw-r--r--source4/printing/printfsp.c120
-rw-r--r--source4/printing/printing.c2128
-rw-r--r--source4/printing/printing_db.c204
-rw-r--r--source4/smbwrapper/PORTING77
-rw-r--r--source4/smbwrapper/README94
-rw-r--r--source4/smbwrapper/realcalls.c48
-rw-r--r--source4/smbwrapper/realcalls.h263
-rw-r--r--source4/smbwrapper/shared.c203
-rw-r--r--source4/smbwrapper/smbsh.c127
-rw-r--r--source4/smbwrapper/smbsh.in54
-rw-r--r--source4/smbwrapper/smbw.c1554
-rw-r--r--source4/smbwrapper/smbw.h71
-rw-r--r--source4/smbwrapper/smbw_cache.c207
-rw-r--r--source4/smbwrapper/smbw_dir.c688
-rw-r--r--source4/smbwrapper/smbw_stat.c250
-rw-r--r--source4/smbwrapper/wrapped.c705
-rw-r--r--source4/web/cgi.c603
-rw-r--r--source4/web/config.m417
-rw-r--r--source4/web/diagnose.c82
-rw-r--r--source4/web/neg_lang.c116
-rw-r--r--source4/web/startstop.c136
-rw-r--r--source4/web/statuspage.c405
-rw-r--r--source4/web/swat.c1343
-rw-r--r--source4/wrepld/parser.c759
-rw-r--r--source4/wrepld/partners.c200
-rw-r--r--source4/wrepld/process.c983
-rw-r--r--source4/wrepld/server.c737
-rw-r--r--source4/wrepld/socket.c69
-rw-r--r--source4/wrepld/wins_repl.h159
107 files changed, 1 insertions, 48153 deletions
diff --git a/source4/include/includes.h b/source4/include/includes.h
index f9598845c3..bc3d948a2c 100644
--- a/source4/include/includes.h
+++ b/source4/include/includes.h
@@ -723,8 +723,6 @@ extern int errno;
#include "mangle.h"
-#include "nsswitch/winbind_client.h"
-
#include "mutex.h"
#include "librpc/rpc/dcerpc.h"
@@ -750,8 +748,6 @@ struct functable {
typedef int (*comparison_fn_t)(const void *, const void *);
#endif
-#include "nsswitch/nss.h"
-
/***** automatically generated prototypes *****/
#include "proto.h"
diff --git a/source4/lib/basic.mk b/source4/lib/basic.mk
index 78acb5bb1c..55254498d9 100644
--- a/source4/lib/basic.mk
+++ b/source4/lib/basic.mk
@@ -43,8 +43,6 @@ ADD_OBJ_FILES = \
lib/tallocmsg.o \
lib/dmallocmsg.o \
lib/smbpasswd.o \
- nsswitch/wb_client.o \
- nsswitch/wb_common.o \
lib/pam_errors.o \
intl/lang_tdb.o \
lib/account_pol.o \
diff --git a/source4/lib/username.c b/source4/lib/username.c
index 3af9dbd027..2d9d212858 100644
--- a/source4/lib/username.c
+++ b/source4/lib/username.c
@@ -169,82 +169,6 @@ struct passwd *Get_Pwnam(const char *user)
}
/****************************************************************************
- 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)
-{
- int num_groups;
- int i;
- gid_t *groups = NULL;
- gid_t gid, gid_low, gid_high;
- BOOL ret = False;
-
- *winbind_answered = False;
-
- if ((gid = nametogid(gname)) == (gid_t)-1) {
- DEBUG(0,("user_in_winbind_group_list: nametogid for group %s failed.\n",
- gname ));
- goto err;
- }
-
- if (!lp_winbind_gid(&gid_low, &gid_high)) {
- DEBUG(4, ("winbind gid range not configured, therefore %s cannot be a winbind group\n", gname));
- goto err;
- }
-
- if (gid < gid_low || gid > gid_high) {
- DEBUG(4, ("group %s is not a winbind group\n", gname));
- goto err;
- }
-
- /*
- * Get the gid's that this user belongs to.
- */
-
- if ((num_groups = winbind_getgroups(user, 0, NULL)) == -1)
- return False;
-
- if (num_groups == 0) {
- *winbind_answered = True;
- return False;
- }
-
- if ((groups = (gid_t *)malloc(sizeof(gid_t) * num_groups )) == NULL) {
- DEBUG(0,("user_in_winbind_group_list: malloc fail.\n"));
- goto err;
- }
-
- if ((num_groups = winbind_getgroups(user, num_groups, groups)) == -1) {
- DEBUG(0,("user_in_winbind_group_list: second winbind_getgroups call \
-failed with error %s\n", strerror(errno) ));
- goto err;
- }
-
- /*
- * Now we have the gid list for this user - convert the gname
- * to a gid_t via either winbind or the local UNIX lookup and do the comparison.
- */
-
- for (i = 0; i < num_groups; i++) {
- if (gid == groups[i]) {
- ret = True;
- break;
- }
- }
-
- *winbind_answered = True;
- SAFE_FREE(groups);
- return ret;
-
- err:
-
- *winbind_answered = False;
- SAFE_FREE(groups);
- return False;
-}
-
-/****************************************************************************
Check if a user is in a UNIX group.
****************************************************************************/
static BOOL user_in_unix_group_list(const char *user,const char *gname)
@@ -298,7 +222,6 @@ exit:
****************************************************************************/
static BOOL user_in_group_list(const char *user, const char *gname, gid_t *groups, size_t n_groups)
{
- BOOL winbind_answered = False;
BOOL ret;
gid_t gid;
unsigned i;
@@ -317,11 +240,7 @@ static BOOL user_in_group_list(const char *user, const char *gname, gid_t *group
}
/* fallback if we don't yet have the group list */
-
- ret = user_in_winbind_group_list(user, gname, &winbind_answered);
- if (!winbind_answered)
- ret = user_in_unix_group_list(user, gname);
-
+ ret = user_in_unix_group_list(user, gname);
if (ret)
DEBUG(10,("user_in_group_list: user |%s| is in group |%s|\n", user, gname));
return ret;
diff --git a/source4/modules/developer.c b/source4/modules/developer.c
deleted file mode 100644
index a697abcd22..0000000000
--- a/source4/modules/developer.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba module with developer tools
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jelmer Vernooij 2002
-
- 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 {
- char from;
- char *to;
- int len;
-} weird_table[] = {
- {'q', "^q^", 3},
- {'Q', "^Q^", 3},
- {0, NULL}
-};
-
-static size_t weird_pull(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- while (*inbytesleft >= 1 && *outbytesleft >= 2) {
- int i;
- int done = 0;
- for (i=0;weird_table[i].from;i++) {
- if (strncmp((*inbuf),
- weird_table[i].to,
- weird_table[i].len) == 0) {
- if (*inbytesleft < weird_table[i].len) {
- DEBUG(0,("ERROR: truncated weird string\n"));
- /* smb_panic("weird_pull"); */
-
- } else {
- (*outbuf)[0] = weird_table[i].from;
- (*outbuf)[1] = 0;
- (*inbytesleft) -= weird_table[i].len;
- (*outbytesleft) -= 2;
- (*inbuf) += weird_table[i].len;
- (*outbuf) += 2;
- done = 1;
- break;
- }
- }
- }
- if (done) continue;
- (*outbuf)[0] = (*inbuf)[0];
- (*outbuf)[1] = 0;
- (*inbytesleft) -= 1;
- (*outbytesleft) -= 2;
- (*inbuf) += 1;
- (*outbuf) += 2;
- }
-
- if (*inbytesleft > 0) {
- errno = E2BIG;
- return -1;
- }
-
- return 0;
-}
-
-static size_t weird_push(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- int ir_count=0;
-
- while (*inbytesleft >= 2 && *outbytesleft >= 1) {
- int i;
- int done=0;
- for (i=0;weird_table[i].from;i++) {
- if ((*inbuf)[0] == weird_table[i].from &&
- (*inbuf)[1] == 0) {
- if (*outbytesleft < weird_table[i].len) {
- DEBUG(0,("No room for weird character\n"));
- /* smb_panic("weird_push"); */
- } else {
- memcpy(*outbuf, weird_table[i].to,
- weird_table[i].len);
- (*inbytesleft) -= 2;
- (*outbytesleft) -= weird_table[i].len;
- (*inbuf) += 2;
- (*outbuf) += weird_table[i].len;
- done = 1;
- break;
- }
- }
- }
- if (done) continue;
-
- (*outbuf)[0] = (*inbuf)[0];
- if ((*inbuf)[1]) ir_count++;
- (*inbytesleft) -= 2;
- (*outbytesleft) -= 1;
- (*inbuf) += 2;
- (*outbuf) += 1;
- }
-
- if (*inbytesleft == 1) {
- errno = EINVAL;
- return -1;
- }
-
- if (*inbytesleft > 1) {
- errno = E2BIG;
- return -1;
- }
-
- return ir_count;
-}
-
-struct charset_functions weird_functions = {"WEIRD", weird_pull, weird_push};
-
-int init_module(void)
-{
- smb_register_charset(&weird_functions);
- return 1;
-}
diff --git a/source4/modules/mysql.c b/source4/modules/mysql.c
deleted file mode 100644
index 1d5819295b..0000000000
--- a/source4/modules/mysql.c
+++ /dev/null
@@ -1,1043 +0,0 @@
-
-/*
- * MySQL password backend for samba
- * Copyright (C) Jelmer Vernooij 2002
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include <mysql/mysql.h>
-
-#define CONFIG_TABLE_DEFAULT "user"
-#define CONFIG_LOGON_TIME_DEFAULT "logon_time"
-#define CONFIG_LOGOFF_TIME_DEFAULT "logoff_time"
-#define CONFIG_KICKOFF_TIME_DEFAULT "kickoff_time"
-#define CONFIG_PASS_LAST_SET_TIME_DEFAULT "pass_last_set_time"
-#define CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT "pass_can_change_time"
-#define CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT "pass_must_change_time"
-#define CONFIG_USERNAME_DEFAULT "username"
-#define CONFIG_DOMAIN_DEFAULT "domain"
-#define CONFIG_NT_USERNAME_DEFAULT "nt_username"
-#define CONFIG_FULLNAME_DEFAULT "nt_fullname"
-#define CONFIG_HOME_DIR_DEFAULT "home_dir"
-#define CONFIG_DIR_DRIVE_DEFAULT "dir_drive"
-#define CONFIG_LOGON_SCRIPT_DEFAULT "logon_script"
-#define CONFIG_PROFILE_PATH_DEFAULT "profile_path"
-#define CONFIG_ACCT_DESC_DEFAULT "acct_desc"
-#define CONFIG_WORKSTATIONS_DEFAULT "workstations"
-#define CONFIG_UNKNOWN_STR_DEFAULT "unknown_str"
-#define CONFIG_MUNGED_DIAL_DEFAULT "munged_dial"
-#define CONFIG_UID_DEFAULT "uid"
-#define CONFIG_GID_DEFAULT "gid"
-#define CONFIG_USER_SID_DEFAULT "user_sid"
-#define CONFIG_GROUP_SID_DEFAULT "group_sid"
-#define CONFIG_LM_PW_DEFAULT "lm_pw"
-#define CONFIG_NT_PW_DEFAULT "nt_pw"
-#define CONFIG_PLAIN_PW_DEFAULT "NULL"
-#define CONFIG_ACCT_CTRL_DEFAULT "acct_ctrl"
-#define CONFIG_UNKNOWN_3_DEFAULT "unknown_3"
-#define CONFIG_LOGON_DIVS_DEFAULT "logon_divs"
-#define CONFIG_HOURS_LEN_DEFAULT "hours_len"
-#define CONFIG_UNKNOWN_5_DEFAULT "unknown_5"
-#define CONFIG_UNKNOWN_6_DEFAULT "unknown_6"
-#define CONFIG_HOST_DEFAULT "localhost"
-#define CONFIG_USER_DEFAULT "samba"
-#define CONFIG_PASS_DEFAULT ""
-#define CONFIG_PORT_DEFAULT "3306"
-#define CONFIG_DB_DEFAULT "samba"
-
-static int mysqlsam_debug_level = DBGC_ALL;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS mysqlsam_debug_level
-
-typedef struct pdb_mysql_data {
- MYSQL *handle;
- MYSQL_RES *pwent;
- const char *location;
-} pdb_mysql_data;
-
-/* Used to construct insert and update queries */
-
-typedef struct pdb_mysql_query {
- char update;
- TALLOC_CTX *mem_ctx;
- char *part1;
- char *part2;
-} pdb_mysql_query;
-#define SET_DATA(data,methods) { \
- if(!methods){ \
- DEBUG(0, ("invalid methods!\n")); \
- return NT_STATUS_INVALID_PARAMETER; \
- } \
- data = (struct pdb_mysql_data *)methods->private_data; \
- if(!data || !(data->handle)){ \
- DEBUG(0, ("invalid handle!\n")); \
- return NT_STATUS_INVALID_HANDLE; \
- } \
-}
-
-static void pdb_mysql_int_field(struct pdb_methods *m,
- struct pdb_mysql_query *q, char *name, int value)
-{
- if (!name || strchr(name, '\''))
- return; /* This field shouldn't be set by us */
-
- if (q->update) {
- q->part1 =
- talloc_asprintf_append(q->mem_ctx, q->part1,
- "%s = %d,", name, value);
- } else {
- q->part1 =
- talloc_asprintf_append(q->mem_ctx, q->part1, "%s,", name);
- q->part2 =
- talloc_asprintf_append(q->mem_ctx, q->part2, "%d,", value);
- }
-}
-
-static NTSTATUS pdb_mysql_string_field(struct pdb_methods *methods,
- struct pdb_mysql_query *q,
- char *name, const char *value)
-{
- char *esc_value;
- struct pdb_mysql_data *data;
- char *tmp_value;
-
- SET_DATA(data, methods);
-
- if (!name || !value || !strcmp(value, "") || strchr(name, '\''))
- return NT_STATUS_INVALID_PARAMETER; /* This field shouldn't be set by module */
-
- esc_value = malloc(strlen(value) * 2 + 1);
-
- tmp_value = smb_xstrdup(value);
- mysql_real_escape_string(data->handle, esc_value, tmp_value,
- strlen(tmp_value));
- SAFE_FREE(tmp_value);
-
- if (q->update) {
- q->part1 =
- talloc_asprintf_append(q->mem_ctx, q->part1,
- "%s = '%s',", name, esc_value);
- } else {
- q->part1 =
- talloc_asprintf_append(q->mem_ctx, q->part1, "%s,", name);
- q->part2 =
- talloc_asprintf_append(q->mem_ctx, q->part2, "'%s',",
- esc_value);
- }
-
- SAFE_FREE(esc_value);
-
- return NT_STATUS_OK;
-}
-
-static char * config_value(pdb_mysql_data * data, char *name, char *default_value)
-{
- if (lp_parm_string(NULL, data->location, name))
- return lp_parm_string(NULL, data->location, name);
-
- return default_value;
-}
-
-static char * config_value_write(pdb_mysql_data * data, char *name, char *default_value) {
- char *v = config_value(data, name, NULL);
- char *swrite;
-
- if (!v)
- return default_value;
-
- swrite = strchr(v, ':');
-
- /* Default to the same field as read field */
- if (!swrite)
- return v;
-
- swrite++;
-
- /* If the field is 0 chars long, we shouldn't write to it */
- if (!strlen(swrite) || !strcmp(swrite, "NULL"))
- return NULL;
-
- /* Otherwise, use the additionally specified */
- return swrite;
-}
-
-static const char * config_value_read(pdb_mysql_data * data, char *name, char *default_value)
-{
- char *v = config_value(data, name, NULL);
- char *swrite;
-
- if (!v)
- return default_value;
-
- swrite = strchr(v, ':');
-
- /* If no write is specified, there are no problems */
- if (!swrite) {
- if (strlen(v) == 0)
- return "NULL";
- return v;
- }
-
- /* Otherwise, we have to cut the ':write_part' */
- *swrite = '\0';
- if (strlen(v) == 0)
- return "NULL";
-
- return v;
-}
-
-/* Wrapper for atol that returns 0 if 'a' points to NULL */
-static long xatol(char *a)
-{
- long ret = 0;
-
- if (a != NULL)
- ret = atol(a);
-
- return ret;
-}
-
-static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u)
-{
- MYSQL_ROW row;
- pstring temp;
- unsigned int num_fields;
- DOM_SID sid;
-
- num_fields = mysql_num_fields(r);
- row = mysql_fetch_row(r);
- if (!row)
- return NT_STATUS_INVALID_PARAMETER;
-
- pdb_set_logon_time(u, xatol(row[0]), PDB_SET);
- pdb_set_logoff_time(u, xatol(row[1]), PDB_SET);
- pdb_set_kickoff_time(u, xatol(row[2]), PDB_SET);
- pdb_set_pass_last_set_time(u, xatol(row[3]), PDB_SET);
- pdb_set_pass_can_change_time(u, xatol(row[4]), PDB_SET);
- pdb_set_pass_must_change_time(u, xatol(row[5]), PDB_SET);
- pdb_set_username(u, row[6], PDB_SET);
- pdb_set_domain(u, row[7], PDB_SET);
- pdb_set_nt_username(u, row[8], PDB_SET);
- pdb_set_fullname(u, row[9], PDB_SET);
- pdb_set_homedir(u, row[10], PDB_SET);
- pdb_set_dir_drive(u, row[11], PDB_SET);
- pdb_set_logon_script(u, row[12], PDB_SET);
- pdb_set_profile_path(u, row[13], PDB_SET);
- pdb_set_acct_desc(u, row[14], PDB_SET);
- pdb_set_workstations(u, row[15], PDB_SET);
- pdb_set_unknown_str(u, row[16], PDB_SET);
- pdb_set_munged_dial(u, row[17], PDB_SET);
-
- if (row[18])
- pdb_set_uid(u, xatol(row[18]), PDB_SET);
- if (row[19])
- pdb_set_gid(u, xatol(row[19]), PDB_SET);
-
- string_to_sid(&sid, row[20]);
- pdb_set_user_sid(u, &sid, PDB_SET);
- string_to_sid(&sid, row[21]);
- pdb_set_group_sid(u, &sid, PDB_SET);
-
- if (pdb_gethexpwd(row[22], temp), PDB_SET)
- pdb_set_lanman_passwd(u, temp, PDB_SET);
- if (pdb_gethexpwd(row[23], temp), PDB_SET)
- pdb_set_nt_passwd(u, temp, PDB_SET);
-
- /* Only use plaintext password storage when lanman and nt are
- * NOT used */
- if (!row[22] || !row[23])
- pdb_set_plaintext_passwd(u, row[24]);
-
- pdb_set_acct_ctrl(u, xatol(row[25]), PDB_SET);
- pdb_set_unknown_3(u, xatol(row[26]), PDB_SET);
- pdb_set_logon_divs(u, xatol(row[27]), PDB_SET);
- pdb_set_hours_len(u, xatol(row[28]), PDB_SET);
- pdb_set_unknown_5(u, xatol(row[29]), PDB_SET);
- pdb_set_unknown_6(u, xatol(row[30]), PDB_SET);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update)
-{
- struct pdb_mysql_data *data =
- (struct pdb_mysql_data *) methods->private_data;
- char *query;
- int ret;
-
- if (!data || !(data->handle)) {
- DEBUG(0, ("invalid handle!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
-
- asprintf(&query,
- "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s",
- config_value_read(data, "logon time column",
- CONFIG_LOGON_TIME_DEFAULT),
- config_value_read(data, "logoff time column",
- CONFIG_LOGOFF_TIME_DEFAULT),
- config_value_read(data, "kickoff time column",
- CONFIG_KICKOFF_TIME_DEFAULT),
- config_value_read(data, "pass last set time column",
- CONFIG_PASS_LAST_SET_TIME_DEFAULT),
- config_value_read(data, "pass can change time column",
- CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT),
- config_value_read(data, "pass must change time column",
- CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT),
- config_value_read(data, "username column",
- CONFIG_USERNAME_DEFAULT),
- config_value_read(data, "domain column",
- CONFIG_DOMAIN_DEFAULT),
- config_value_read(data, "nt username column",
- CONFIG_NT_USERNAME_DEFAULT),
- config_value_read(data, "fullname column",
- CONFIG_FULLNAME_DEFAULT),
- config_value_read(data, "home dir column",
- CONFIG_HOME_DIR_DEFAULT),
- config_value_read(data, "dir drive column",
- CONFIG_DIR_DRIVE_DEFAULT),
- config_value_read(data, "logon script column",
- CONFIG_LOGON_SCRIPT_DEFAULT),
- config_value_read(data, "profile path column",
- CONFIG_PROFILE_PATH_DEFAULT),
- config_value_read(data, "acct desc column",
- CONFIG_ACCT_DESC_DEFAULT),
- config_value_read(data, "workstations column",
- CONFIG_WORKSTATIONS_DEFAULT),
- config_value_read(data, "unknown string column",
- CONFIG_UNKNOWN_STR_DEFAULT),
- config_value_read(data, "munged dial column",
- CONFIG_MUNGED_DIAL_DEFAULT),
- config_value_read(data, "uid column", CONFIG_UID_DEFAULT),
- config_value_read(data, "gid column", CONFIG_GID_DEFAULT),
- config_value_read(data, "user sid column",
- CONFIG_USER_SID_DEFAULT),
- config_value_read(data, "group sid column",
- CONFIG_GROUP_SID_DEFAULT),
- config_value_read(data, "lanman pass column",
- CONFIG_LM_PW_DEFAULT),
- config_value_read(data, "nt pass column",
- CONFIG_NT_PW_DEFAULT),
- config_value_read(data, "plain pass column",
- CONFIG_PLAIN_PW_DEFAULT),
- config_value_read(data, "acct ctrl column",
- CONFIG_ACCT_CTRL_DEFAULT),
- config_value_read(data, "unknown 3 column",
- CONFIG_UNKNOWN_3_DEFAULT),
- config_value_read(data, "logon divs column",
- CONFIG_LOGON_DIVS_DEFAULT),
- config_value_read(data, "hours len column",
- CONFIG_HOURS_LEN_DEFAULT),
- config_value_read(data, "unknown 5 column",
- CONFIG_UNKNOWN_5_DEFAULT),
- config_value_read(data, "unknown 6 column",
- CONFIG_UNKNOWN_6_DEFAULT),
- config_value(data, "table", CONFIG_TABLE_DEFAULT)
- );
- DEBUG(5, ("Executing query %s\n", query));
-
- ret = mysql_query(data->handle, query);
- SAFE_FREE(query);
-
- if (ret) {
- DEBUG(0,
- ("Error executing MySQL query %s\n", mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- data->pwent = mysql_store_result(data->handle);
-
- if (data->pwent == NULL) {
- DEBUG(0,
- ("Error storing results: %s\n", mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5,
- ("mysqlsam_setsampwent succeeded(%lu results)!\n",
- mysql_num_rows(data->pwent)));
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************
- End enumeration of the passwd list.
- ****************************************************************/
-
-static void mysqlsam_endsampwent(struct pdb_methods *methods)
-{
- struct pdb_mysql_data *data =
- (struct pdb_mysql_data *) methods->private_data;
-
- if (data == NULL) {
- DEBUG(0, ("invalid handle!\n"));
- return;
- }
-
- if (data->pwent != NULL)
- mysql_free_result(data->pwent);
-
- data->pwent = NULL;
-
- DEBUG(5, ("mysql_endsampwent called\n"));
-}
-
-/*****************************************************************
- Get one SAM_ACCOUNT from the list (next in line)
- *****************************************************************/
-
-static NTSTATUS mysqlsam_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT * user)
-{
- struct pdb_mysql_data *data;
-
- SET_DATA(data, methods);
-
- if (data->pwent == NULL) {
- DEBUG(0, ("invalid pwent\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- return row_to_sam_account(data->pwent, user);
-}
-
-static NTSTATUS mysqlsam_select_by_field(struct pdb_methods * methods, SAM_ACCOUNT * user,
- const char *field, const char *sname)
-{
- char *esc_sname;
- char *query;
- NTSTATUS ret;
- MYSQL_RES *res;
- int mysql_ret;
- struct pdb_mysql_data *data;
- char *tmp_sname;
-
- SET_DATA(data, methods);
-
- esc_sname = malloc(strlen(sname) * 2 + 1);
- if (!esc_sname) {
- return NT_STATUS_NO_MEMORY;
- }
-
- DEBUG(5,
- ("mysqlsam_select_by_field: getting data where %s = %s(nonescaped)\n",
- field, sname));
-
- tmp_sname = smb_xstrdup(sname);
-
- /* Escape sname */
- mysql_real_escape_string(data->handle, esc_sname, tmp_sname,
- strlen(tmp_sname));
-
- SAFE_FREE(tmp_sname);
-
- if (user == NULL) {
- DEBUG(0, ("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n"));
- SAFE_FREE(esc_sname);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- asprintf(&query,
- "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s WHERE %s = '%s'",
- config_value_read(data, "logon time column",
- CONFIG_LOGON_TIME_DEFAULT),
- config_value_read(data, "logoff time column",
- CONFIG_LOGOFF_TIME_DEFAULT),
- config_value_read(data, "kickoff time column",
- CONFIG_KICKOFF_TIME_DEFAULT),
- config_value_read(data, "pass last set time column",
- CONFIG_PASS_LAST_SET_TIME_DEFAULT),
- config_value_read(data, "pass can change time column",
- CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT),
- config_value_read(data, "pass must change time column",
- CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT),
- config_value_read(data, "username column",
- CONFIG_USERNAME_DEFAULT),
- config_value_read(data, "domain column",
- CONFIG_DOMAIN_DEFAULT),
- config_value_read(data, "nt username column",
- CONFIG_NT_USERNAME_DEFAULT),
- config_value_read(data, "fullname column",
- CONFIG_FULLNAME_DEFAULT),
- config_value_read(data, "home dir column",
- CONFIG_HOME_DIR_DEFAULT),
- config_value_read(data, "dir drive column",
- CONFIG_DIR_DRIVE_DEFAULT),
- config_value_read(data, "logon script column",
- CONFIG_LOGON_SCRIPT_DEFAULT),
- config_value_read(data, "profile path column",
- CONFIG_PROFILE_PATH_DEFAULT),
- config_value_read(data, "acct desc column",
- CONFIG_ACCT_DESC_DEFAULT),
- config_value_read(data, "workstations column",
- CONFIG_WORKSTATIONS_DEFAULT),
- config_value_read(data, "unknown string column",
- CONFIG_UNKNOWN_STR_DEFAULT),
- config_value_read(data, "munged dial column",
- CONFIG_MUNGED_DIAL_DEFAULT),
- config_value_read(data, "uid column", CONFIG_UID_DEFAULT),
- config_value_read(data, "gid column", CONFIG_GID_DEFAULT),
- config_value_read(data, "user sid column",
- CONFIG_USER_SID_DEFAULT),
- config_value_read(data, "group sid column",
- CONFIG_GROUP_SID_DEFAULT),
- config_value_read(data, "lanman pass column",
- CONFIG_LM_PW_DEFAULT),
- config_value_read(data, "nt pass column",
- CONFIG_NT_PW_DEFAULT),
- config_value_read(data, "plain pass column",
- CONFIG_PLAIN_PW_DEFAULT),
- config_value_read(data, "acct ctrl column",
- CONFIG_ACCT_CTRL_DEFAULT),
- config_value_read(data, "unknown 3 column",
- CONFIG_UNKNOWN_3_DEFAULT),
- config_value_read(data, "logon divs column",
- CONFIG_LOGON_DIVS_DEFAULT),
- config_value_read(data, "hours len column",
- CONFIG_HOURS_LEN_DEFAULT),
- config_value_read(data, "unknown 5 column",
- CONFIG_UNKNOWN_5_DEFAULT),
- config_value_read(data, "unknown 6 column",
- CONFIG_UNKNOWN_6_DEFAULT),
- config_value(data, "table", CONFIG_TABLE_DEFAULT), field,
- esc_sname);
-
- SAFE_FREE(esc_sname);
-
- DEBUG(5, ("Executing query %s\n", query));
-
- mysql_ret = mysql_query(data->handle, query);
-
- SAFE_FREE(query);
-
- if (mysql_ret) {
- DEBUG(0,
- ("Error while executing MySQL query %s\n",
- mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- res = mysql_store_result(data->handle);
- if (res == NULL) {
- DEBUG(0,
- ("Error storing results: %s\n", mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ret = row_to_sam_account(res, user);
- mysql_free_result(res);
-
- return ret;
-}
-
-/******************************************************************
- Lookup a name in the SAM database
- ******************************************************************/
-
-static NTSTATUS mysqlsam_getsampwnam(struct pdb_methods *methods, SAM_ACCOUNT * user,
- const char *sname)
-{
- struct pdb_mysql_data *data;
-
- SET_DATA(data, methods);
-
- if (!sname) {
- DEBUG(0, ("invalid name specified"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- return mysqlsam_select_by_field(methods, user,
- config_value_read(data, "username column",
- CONFIG_USERNAME_DEFAULT), sname);
-}
-
-
-/***************************************************************************
- Search by sid
- **************************************************************************/
-
-static NTSTATUS mysqlsam_getsampwsid(struct pdb_methods *methods, SAM_ACCOUNT * user,
- const DOM_SID * sid)
-{
- struct pdb_mysql_data *data;
- fstring sid_str;
-
- SET_DATA(data, methods);
-
- sid_to_string(sid_str, sid);
-
- return mysqlsam_select_by_field(methods, user,
- config_value_read(data, "user sid column",
- CONFIG_USER_SID_DEFAULT), sid_str);
-}
-
-/***************************************************************************
- Delete a SAM_ACCOUNT
- ****************************************************************************/
-
-static NTSTATUS mysqlsam_delete_sam_account(struct pdb_methods *methods,
- SAM_ACCOUNT * sam_pass)
-{
- const char *sname = pdb_get_username(sam_pass);
- char *esc;
- char *query;
- int ret;
- struct pdb_mysql_data *data;
- char *tmp_sname;
-
- SET_DATA(data, methods);
-
- if (!methods) {
- DEBUG(0, ("invalid methods!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data = (struct pdb_mysql_data *) methods->private_data;
- if (!data || !(data->handle)) {
- DEBUG(0, ("invalid handle!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
-
- if (!sname) {
- DEBUG(0, ("invalid name specified\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* Escape sname */
- esc = malloc(strlen(sname) * 2 + 1);
- if (!esc) {
- DEBUG(0, ("Can't allocate memory to store escaped name\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- tmp_sname = smb_xstrdup(sname);
-
- mysql_real_escape_string(data->handle, esc, tmp_sname,
- strlen(tmp_sname));
-
- SAFE_FREE(tmp_sname);
-
- asprintf(&query, "DELETE FROM %s WHERE %s = '%s'",
- config_value(data, "table", CONFIG_TABLE_DEFAULT),
- config_value_read(data, "username column",
- CONFIG_USERNAME_DEFAULT), esc);
-
- SAFE_FREE(esc);
-
- ret = mysql_query(data->handle, query);
-
- SAFE_FREE(query);
-
- if (ret) {
- DEBUG(0,
- ("Error while executing query: %s\n",
- mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5, ("User '%s' deleted\n", sname));
- return NT_STATUS_OK;
-}
-
-static NTSTATUS mysqlsam_replace_sam_account(struct pdb_methods *methods,
- const SAM_ACCOUNT * newpwd, char isupdate)
-{
- pstring temp;
- struct pdb_mysql_data *data;
- pdb_mysql_query query;
- fstring sid_str;
-
- if (!methods) {
- DEBUG(0, ("invalid methods!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data = (struct pdb_mysql_data *) methods->private_data;
- if (data == NULL || data->handle == NULL) {
- DEBUG(0, ("invalid handle!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
- query.update = isupdate;
-
- /* I know this is somewhat overkill but only the talloc
- * functions have asprint_append and the 'normal' asprintf
- * is a GNU extension */
- query.mem_ctx = talloc_init("mysqlsam_replace_sam_account");
- query.part2 = talloc_asprintf(query.mem_ctx, "%s", "");
- if (query.update) {
- query.part1 =
- talloc_asprintf(query.mem_ctx, "UPDATE %s SET ",
- config_value(data, "table",
- CONFIG_TABLE_DEFAULT));
- } else {
- query.part1 =
- talloc_asprintf(query.mem_ctx, "INSERT INTO %s (",
- config_value(data, "table",
- CONFIG_TABLE_DEFAULT));
- }
-
- pdb_mysql_int_field(methods, &query,
- config_value_write(data, "acct ctrl column",
- CONFIG_ACCT_CTRL_DEFAULT),
- pdb_get_acct_ctrl(newpwd));
-
- if (pdb_get_init_flags(newpwd, PDB_LOGONTIME) != PDB_DEFAULT) {
- pdb_mysql_int_field(methods, &query,
- config_value_write(data,
- "logon time column",
- CONFIG_LOGON_TIME_DEFAULT),
- pdb_get_logon_time(newpwd));
- }
-
- if (pdb_get_init_flags(newpwd, PDB_LOGOFFTIME) != PDB_DEFAULT) {
- pdb_mysql_int_field(methods, &query,
- config_value_write(data,
- "logoff time column",
- CONFIG_LOGOFF_TIME_DEFAULT),
- pdb_get_logoff_time(newpwd));
- }
-
- if (pdb_get_init_flags(newpwd, PDB_KICKOFFTIME) != PDB_DEFAULT) {
- pdb_mysql_int_field(methods, &query,
- config_value_write(data,
- "kickoff time column",
- CONFIG_KICKOFF_TIME_DEFAULT),
- pdb_get_kickoff_time(newpwd));
- }
-
- if (pdb_get_init_flags(newpwd, PDB_CANCHANGETIME) != PDB_DEFAULT) {
- pdb_mysql_int_field(methods, &query,
- config_value_write(data,
- "pass can change time column",
- CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT),
- pdb_get_pass_can_change_time(newpwd));
- }
-
- if (pdb_get_init_flags(newpwd, PDB_MUSTCHANGETIME) != PDB_DEFAULT) {
- pdb_mysql_int_field(methods, &query,
- config_value_write(data,
- "pass must change time column",
- CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT),
- pdb_get_pass_must_change_time(newpwd));
- }
-
- if (pdb_get_pass_last_set_time(newpwd)) {
- pdb_mysql_int_field(methods, &query,
- config_value_write(data,
- "pass last set time column",
- CONFIG_PASS_LAST_SET_TIME_DEFAULT),
- pdb_get_pass_last_set_time(newpwd));
- }
-
- if (pdb_get_hours_len(newpwd)) {
- pdb_mysql_int_field(methods, &query,
- config_value_write(data,
- "hours len column",
- CONFIG_HOURS_LEN_DEFAULT),
- pdb_get_hours_len(newpwd));
- }
-
- if (pdb_get_logon_divs(newpwd)) {
- pdb_mysql_int_field(methods, &query,
- config_value_write(data,
- "logon divs column",
- CONFIG_LOGON_DIVS_DEFAULT),
- pdb_get_logon_divs(newpwd));
- }
-
- if (pdb_get_init_flags(newpwd, PDB_UID) != PDB_DEFAULT) {
- pdb_mysql_int_field(methods, &query,
- config_value_write(data, "uid column",
- CONFIG_UID_DEFAULT),
- pdb_get_uid(newpwd));
- }
-
- if (pdb_get_init_flags(newpwd, PDB_GID) != PDB_DEFAULT) {
- pdb_mysql_int_field(methods, &query,
- config_value_write(data, "gid column",
- CONFIG_GID_DEFAULT),
- pdb_get_gid(newpwd));
- }
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data, "user sid column",
- CONFIG_USER_SID_DEFAULT),
- sid_to_string(sid_str,
- pdb_get_user_sid(newpwd)));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data, "group sid column",
- CONFIG_GROUP_SID_DEFAULT),
- sid_to_string(sid_str,
- pdb_get_group_sid(newpwd)));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data, "username column",
- CONFIG_USERNAME_DEFAULT),
- pdb_get_username(newpwd));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data, "domain column",
- CONFIG_DOMAIN_DEFAULT),
- pdb_get_domain(newpwd));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data,
- "nt username column",
- CONFIG_NT_USERNAME_DEFAULT),
- pdb_get_nt_username(newpwd));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data, "fullname column",
- CONFIG_FULLNAME_DEFAULT),
- pdb_get_fullname(newpwd));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data,
- "logon script column",
- CONFIG_LOGON_SCRIPT_DEFAULT),
- pdb_get_logon_script(newpwd));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data,
- "profile path column",
- CONFIG_PROFILE_PATH_DEFAULT),
- pdb_get_profile_path(newpwd));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data, "dir drive column",
- CONFIG_DIR_DRIVE_DEFAULT),
- pdb_get_dir_drive(newpwd));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data, "home dir column",
- CONFIG_HOME_DIR_DEFAULT),
- pdb_get_homedir(newpwd));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data,
- "workstations column",
- CONFIG_WORKSTATIONS_DEFAULT),
- pdb_get_workstations(newpwd));
-
- pdb_mysql_string_field(methods, &query,
- config_value_write(data,
- "unknown string column",
- CONFIG_UNKNOWN_STR_DEFAULT),
- pdb_get_workstations(newpwd));
-
- pdb_sethexpwd(temp, pdb_get_lanman_passwd(newpwd),
- pdb_get_acct_ctrl(newpwd));
- pdb_mysql_string_field(methods, &query,
- config_value_write(data,
- "lanman pass column",
- CONFIG_LM_PW_DEFAULT), temp);
-
- pdb_sethexpwd(temp, pdb_get_nt_passwd(newpwd),
- pdb_get_acct_ctrl(newpwd));
- pdb_mysql_string_field(methods, &query,
- config_value_write(data, "nt pass column",
- CONFIG_NT_PW_DEFAULT), temp);
-
- if (query.update) {
- query.part1[strlen(query.part1) - 1] = '\0';
- query.part1 =
- talloc_asprintf_append(query.mem_ctx, query.part1,
- " WHERE %s = '%s'",
- config_value_read(data,
- "user sid column",
- CONFIG_USER_SID_DEFAULT),
- sid_to_string(sid_str, pdb_get_user_sid (newpwd)));
- } else {
- query.part2[strlen(query.part2) - 1] = ')';
- query.part1[strlen(query.part1) - 1] = ')';
- query.part1 =
- talloc_asprintf_append(query.mem_ctx, query.part1,
- " VALUES (%s", query.part2);
- }
-
- DEBUG(0, ("%s\n", query.part1));
- /* Execute the query */
- if (mysql_query(data->handle, query.part1)) {
- DEBUG(0,
- ("Error executing %s, %s\n", query.part1,
- mysql_error(data->handle)));
- return NT_STATUS_INVALID_PARAMETER;
- }
- talloc_destroy(query.mem_ctx);
- return NT_STATUS_OK;
-}
-
-static NTSTATUS mysqlsam_add_sam_account(struct pdb_methods *methods, SAM_ACCOUNT * newpwd)
-{
- return mysqlsam_replace_sam_account(methods, newpwd, 0);
-}
-
-static NTSTATUS mysqlsam_update_sam_account(struct pdb_methods *methods,
- SAM_ACCOUNT * newpwd)
-{
- return mysqlsam_replace_sam_account(methods, newpwd, 1);
-}
-
-static NTSTATUS mysqlsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
- DOM_SID sid, BOOL with_priv)
-{
- return get_group_map_from_sid(sid, map, with_priv) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
- gid_t gid, BOOL with_priv)
-{
- return get_group_map_from_gid(gid, map, with_priv) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
- char *name, BOOL with_priv)
-{
- return get_group_map_from_ntname(name, map, with_priv) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_add_group_mapping_entry(struct pdb_methods *methods,
- GROUP_MAP *map)
-{
- return add_mapping_entry(map, TDB_INSERT) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_update_group_mapping_entry(struct pdb_methods *methods,
- GROUP_MAP *map)
-{
- return add_mapping_entry(map, TDB_REPLACE) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_delete_group_mapping_entry(struct pdb_methods *methods,
- DOM_SID sid)
-{
- return group_map_remove(sid) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_enum_group_mapping(struct pdb_methods *methods,
- enum SID_NAME_USE sid_name_use,
- GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only, BOOL with_priv)
-{
- return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only,
- with_priv) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_methods ** pdb_method,
- const char *location)
-{
- NTSTATUS nt_status;
- struct pdb_mysql_data *data;
-
- mysqlsam_debug_level = debug_add_class("mysqlsam");
- if (mysqlsam_debug_level == -1) {
- mysqlsam_debug_level = DBGC_ALL;
- DEBUG(0,
- ("mysqlsam: Couldn't register custom debugging class!\n"));
- }
-
- if (!pdb_context) {
- DEBUG(0, ("invalid pdb_methods specified\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK
- (nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "mysqlsam";
-
- (*pdb_method)->setsampwent = mysqlsam_setsampwent;
- (*pdb_method)->endsampwent = mysqlsam_endsampwent;
- (*pdb_method)->getsampwent = mysqlsam_getsampwent;
- (*pdb_method)->getsampwnam = mysqlsam_getsampwnam;
- (*pdb_method)->getsampwsid = mysqlsam_getsampwsid;
- (*pdb_method)->add_sam_account = mysqlsam_add_sam_account;
- (*pdb_method)->update_sam_account = mysqlsam_update_sam_account;
- (*pdb_method)->delete_sam_account = mysqlsam_delete_sam_account;
- (*pdb_method)->getgrsid = mysqlsam_getgrsid;
- (*pdb_method)->getgrgid = mysqlsam_getgrgid;
- (*pdb_method)->getgrnam = mysqlsam_getgrnam;
- (*pdb_method)->add_group_mapping_entry = mysqlsam_add_group_mapping_entry;
- (*pdb_method)->update_group_mapping_entry = mysqlsam_update_group_mapping_entry;
- (*pdb_method)->delete_group_mapping_entry = mysqlsam_delete_group_mapping_entry;
- (*pdb_method)->enum_group_mapping = mysqlsam_enum_group_mapping;
-
- data = talloc(pdb_context->mem_ctx, sizeof(struct pdb_mysql_data));
- (*pdb_method)->private_data = data;
- data->handle = NULL;
- data->pwent = NULL;
-
- if (!location) {
- DEBUG(0, ("No identifier specified. See README for details\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data->location = smb_xstrdup(location);
-
- DEBUG(1,
- ("Connecting to database server, host: %s, user: %s, password: %s, database: %s, port: %ld\n",
- config_value(data, "mysql host", CONFIG_HOST_DEFAULT),
- config_value(data, "mysql user", CONFIG_USER_DEFAULT),
- config_value(data, "mysql password", CONFIG_PASS_DEFAULT),
- config_value(data, "mysql database", CONFIG_DB_DEFAULT),
- xatol(config_value(data, "mysql port", CONFIG_PORT_DEFAULT))));
-
- /* Do the mysql initialization */
- data->handle = mysql_init(NULL);
- if (!data->handle) {
- DEBUG(0, ("Failed to connect to server\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
- /* Process correct entry in $HOME/.my.conf */
- if (!mysql_real_connect(data->handle,
- config_value(data, "mysql host", CONFIG_HOST_DEFAULT),
- config_value(data, "mysql user", CONFIG_USER_DEFAULT),
- config_value(data, "mysql password", CONFIG_PASS_DEFAULT),
- config_value(data, "mysql database", CONFIG_DB_DEFAULT),
- xatol(config_value (data, "mysql port", CONFIG_PORT_DEFAULT)),
- NULL, 0)) {
- DEBUG(0,
- ("Failed to connect to mysql database: error: %s\n",
- mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5, ("Connected to mysql db\n"));
-
- return NT_STATUS_OK;
-}
-
-int init_module(void);
-
-int init_module()
-{
- if(smb_register_passdb("mysql", mysqlsam_init, PASSDB_INTERFACE_VERSION))
- return 0;
-
- return 1;
-}
diff --git a/source4/modules/vfs_audit.c b/source4/modules/vfs_audit.c
deleted file mode 100644
index b99d93d0f0..0000000000
--- a/source4/modules/vfs_audit.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Auditing VFS module for samba. Log selected file operations to syslog
- * facility.
- *
- * Copyright (C) Tim Potter, 1999-2000
- * Copyright (C) Alexander Bokovoy, 2002
- *
- * 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 "config.h"
-#include <stdio.h>
-#include <sys/stat.h>
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#include <syslog.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <errno.h>
-#include <string.h>
-#include <includes.h>
-#include <vfs.h>
-
-#ifndef SYSLOG_FACILITY
-#define SYSLOG_FACILITY LOG_USER
-#endif
-
-#ifndef SYSLOG_PRIORITY
-#define SYSLOG_PRIORITY LOG_NOTICE
-#endif
-
-/* Function prototypes */
-
-static int audit_connect(struct tcon_context *conn, const char *svc, const char *user);
-static void audit_disconnect(struct tcon_context *conn);
-static DIR *audit_opendir(struct tcon_context *conn, const char *fname);
-static int audit_mkdir(struct tcon_context *conn, const char *path, mode_t mode);
-static int audit_rmdir(struct tcon_context *conn, const char *path);
-static int audit_open(struct tcon_context *conn, const char *fname, int flags, mode_t mode);
-static int audit_close(struct files_struct *fsp, int fd);
-static int audit_rename(struct tcon_context *conn, const char *old, const char *new);
-static int audit_unlink(struct tcon_context *conn, const char *path);
-static int audit_chmod(struct tcon_context *conn, const char *path, mode_t mode);
-static int audit_chmod_acl(struct tcon_context *conn, const char *name, mode_t mode);
-static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode);
-static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode);
-
-/* VFS operations */
-
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *audit_handle;
-
-static vfs_op_tuple audit_ops[] = {
-
- /* Disk operations */
-
- {audit_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER},
- {audit_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER},
-
- /* Directory operations */
-
- {audit_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER},
- {audit_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER},
- {audit_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER},
-
- /* File operations */
-
- {audit_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER},
- {audit_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER},
- {audit_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER},
- {audit_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER},
- {audit_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER},
- {audit_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER},
- {audit_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER},
- {audit_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER},
-
- /* Finish VFS operations definition */
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
-
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
-{
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- audit_handle = vfs_handle;
-
- openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY);
- syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n");
- return audit_ops;
-}
-
-/* VFS finalization function. */
-void vfs_done(struct tcon_context *conn)
-{
- syslog(SYSLOG_PRIORITY, "VFS_DONE: vfs module unloaded\n");
-}
-
-/* Implementation of vfs_ops. Pass everything on to the default
- operation but log event first. */
-
-static int audit_connect(struct tcon_context *conn, const char *svc, const char *user)
-{
- syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n",
- svc, user);
-
- return default_vfs_ops.connect(conn, svc, user);
-}
-
-static void audit_disconnect(struct tcon_context *conn)
-{
- syslog(SYSLOG_PRIORITY, "disconnected\n");
- default_vfs_ops.disconnect(conn);
-}
-
-static DIR *audit_opendir(struct tcon_context *conn, const char *fname)
-{
- DIR *result = default_vfs_ops.opendir(conn, fname);
-
- syslog(SYSLOG_PRIORITY, "opendir %s %s%s\n",
- fname,
- (result == NULL) ? "failed: " : "",
- (result == NULL) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_mkdir(struct tcon_context *conn, const char *path, mode_t mode)
-{
- int result = default_vfs_ops.mkdir(conn, path, mode);
-
- syslog(SYSLOG_PRIORITY, "mkdir %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_rmdir(struct tcon_context *conn, const char *path)
-{
- int result = default_vfs_ops.rmdir(conn, path);
-
- syslog(SYSLOG_PRIORITY, "rmdir %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_open(struct tcon_context *conn, const char *fname, int flags, mode_t mode)
-{
- int result = default_vfs_ops.open(conn, fname, flags, mode);
-
- syslog(SYSLOG_PRIORITY, "open %s (fd %d) %s%s%s\n",
- fname, result,
- ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_close(struct files_struct *fsp, int fd)
-{
- int result = default_vfs_ops.close(fsp, fd);
-
- syslog(SYSLOG_PRIORITY, "close fd %d %s%s\n",
- fd,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_rename(struct tcon_context *conn, const char *old, const char *new)
-{
- int result = default_vfs_ops.rename(conn, old, new);
-
- syslog(SYSLOG_PRIORITY, "rename %s -> %s %s%s\n",
- old, new,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_unlink(struct tcon_context *conn, const char *path)
-{
- int result = default_vfs_ops.unlink(conn, path);
-
- syslog(SYSLOG_PRIORITY, "unlink %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_chmod(struct tcon_context *conn, const char *path, mode_t mode)
-{
- int result = default_vfs_ops.chmod(conn, path, mode);
-
- syslog(SYSLOG_PRIORITY, "chmod %s mode 0x%x %s%s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_chmod_acl(struct tcon_context *conn, const char *path, mode_t mode)
-{
- int result;
-
- if ( !default_vfs_ops.chmod_acl )
- return 0;
-
- result = default_vfs_ops.chmod_acl(conn, path, mode);
-
- syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
-{
- int result = default_vfs_ops.fchmod(fsp, fd, mode);
-
- syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
-{
- int result;
-
- if ( !default_vfs_ops.fchmod_acl )
- return 0;
-
- result = default_vfs_ops.fchmod_acl(fsp, fd, mode);
-
- syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
diff --git a/source4/modules/vfs_extd_audit.c b/source4/modules/vfs_extd_audit.c
deleted file mode 100644
index e9b6ed5455..0000000000
--- a/source4/modules/vfs_extd_audit.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Auditing VFS module for samba. Log selected file operations to syslog
- * facility.
- *
- * Copyright (C) Tim Potter, 1999-2000
- * Copyright (C) Alexander Bokovoy, 2002
- * Copyright (C) John H Terpstra, 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 "config.h"
-#include <stdio.h>
-#include <sys/stat.h>
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#include <syslog.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <errno.h>
-#include <string.h>
-#include <includes.h>
-#include <vfs.h>
-
-#ifndef SYSLOG_FACILITY
-#define SYSLOG_FACILITY LOG_USER
-#endif
-
-#ifndef SYSLOG_PRIORITY
-#define SYSLOG_PRIORITY LOG_NOTICE
-#endif
-
-/* Function prototypes */
-
-static int audit_connect(struct tcon_context *conn, const char *svc, const char *user);
-static void audit_disconnect(struct tcon_context *conn);
-static DIR *audit_opendir(struct tcon_context *conn, const char *fname);
-static int audit_mkdir(struct tcon_context *conn, const char *path, mode_t mode);
-static int audit_rmdir(struct tcon_context *conn, const char *path);
-static int audit_open(struct tcon_context *conn, const char *fname, int flags, mode_t mode);
-static int audit_close(struct files_struct *fsp, int fd);
-static int audit_rename(struct tcon_context *conn, const char *old, const char *new);
-static int audit_unlink(struct tcon_context *conn, const char *path);
-static int audit_chmod(struct tcon_context *conn, const char *path, mode_t mode);
-static int audit_chmod_acl(struct tcon_context *conn, const char *name, mode_t mode);
-static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode);
-static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode);
-
-/* VFS operations */
-
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *audit_handle;
-
-static vfs_op_tuple audit_ops[] = {
-
- /* Disk operations */
-
- {audit_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER},
- {audit_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER},
-
- /* Directory operations */
-
- {audit_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER},
- {audit_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER},
- {audit_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER},
-
- /* File operations */
-
- {audit_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER},
- {audit_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER},
- {audit_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER},
- {audit_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER},
- {audit_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER},
- {audit_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER},
- {audit_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER},
- {audit_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER},
-
- /* Finish VFS operations definition */
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
-
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
-{
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- audit_handle = vfs_handle;
-
- openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY);
- syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n");
-
- return audit_ops;
-}
-
-/* VFS finalization function. */
-
-void vfs_done(struct tcon_context *conn)
-{
- syslog(SYSLOG_PRIORITY, "VFS_DONE: vfs module unloaded\n");
-}
-
-/* Implementation of vfs_ops. Pass everything on to the default
- operation but log event first. */
-
-static int audit_connect(struct tcon_context *conn, const char *svc, const char *user)
-{
- syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n",
- svc, user);
- DEBUG(10, ("Connected to service %s as user %s\n",
- svc, user));
-
- return default_vfs_ops.connect(conn, svc, user);
-}
-
-static void audit_disconnect(struct tcon_context *conn)
-{
- syslog(SYSLOG_PRIORITY, "disconnected\n");
- DEBUG(10, ("Disconnected from VFS module extd_audit\n"));
-
- default_vfs_ops.disconnect(conn);
-}
-
-static DIR *audit_opendir(struct tcon_context *conn, const char *fname)
-{
- DIR *result = default_vfs_ops.opendir(conn, fname);
-
- syslog(SYSLOG_PRIORITY, "opendir %s %s%s\n",
- fname,
- (result == NULL) ? "failed: " : "",
- (result == NULL) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: opendir %s %s %s",
- fname,
- (result == NULL) ? "failed: " : "",
- (result == NULL) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_mkdir(struct tcon_context *conn, const char *path, mode_t mode)
-{
- int result = default_vfs_ops.mkdir(conn, path, mode);
-
- syslog(SYSLOG_PRIORITY, "mkdir %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(0, ("vfs_extd_audit: mkdir %s %s %s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_rmdir(struct tcon_context *conn, const char *path)
-{
- int result = default_vfs_ops.rmdir(conn, path);
-
- syslog(SYSLOG_PRIORITY, "rmdir %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(0, ("vfs_extd_audit: rmdir %s %s %s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_open(struct tcon_context *conn, const char *fname, int flags, mode_t mode)
-{
- int result = default_vfs_ops.open(conn, fname, flags, mode);
-
- syslog(SYSLOG_PRIORITY, "open %s (fd %d) %s%s%s\n",
- fname, result,
- ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(2, ("vfs_extd_audit: open %s %s %s\n",
- fname,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_close(struct files_struct *fsp, int fd)
-{
- int result = default_vfs_ops.close(fsp, fd);
-
- syslog(SYSLOG_PRIORITY, "close fd %d %s%s\n",
- fd,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(2, ("vfs_extd_audit: close fd %d %s %s\n",
- fd,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_rename(struct tcon_context *conn, const char *old, const char *new)
-{
- int result = default_vfs_ops.rename(conn, old, new);
-
- syslog(SYSLOG_PRIORITY, "rename %s -> %s %s%s\n",
- old, new,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: rename old: %s new: %s %s %s\n",
- old, new,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_unlink(struct tcon_context *conn, const char *path)
-{
- int result = default_vfs_ops.unlink(conn, path);
-
- syslog(SYSLOG_PRIORITY, "unlink %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(0, ("vfs_extd_audit: unlink %s %s %s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_chmod(struct tcon_context *conn, const char *path, mode_t mode)
-{
- int result = default_vfs_ops.chmod(conn, path, mode);
-
- syslog(SYSLOG_PRIORITY, "chmod %s mode 0x%x %s%s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: chmod %s mode 0x%x %s %s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_chmod_acl(struct tcon_context *conn, const char *path, mode_t mode)
-{
- int result = default_vfs_ops.chmod_acl(conn, path, mode);
-
- syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: chmod_acl %s mode 0x%x %s %s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
-{
- int result = default_vfs_ops.fchmod(fsp, fd, mode);
-
- syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
-{
- int result = default_vfs_ops.fchmod_acl(fsp, fd, mode);
-
- syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
diff --git a/source4/modules/vfs_fake_perms.c b/source4/modules/vfs_fake_perms.c
deleted file mode 100644
index 63ef66c591..0000000000
--- a/source4/modules/vfs_fake_perms.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * Fake Perms VFS module. Implements passthrough operation of all VFS
- * calls to disk functions, except for file permissions, which are now
- * mode 0700 for the current uid/gid.
- *
- * Copyright (C) Tim Potter, 1999-2000
- * Copyright (C) Alexander Bokovoy, 2002
- * Copyright (C) Andrew Bartlett, 2002
- *
- * 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 "config.h"
-
-#include <stdio.h>
-#include <sys/stat.h>
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <errno.h>
-#include <string.h>
-
-#include <includes.h>
-#include <vfs.h>
-
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *fake_perms_handle; /* use fake_perms_handle->data for storing per-instance private data */
-
-static int fake_perms_connect(struct tcon_context *conn, const char *service, const char *user)
-{
- return default_vfs_ops.connect(conn, service, user);
-}
-
-static void fake_perms_disconnect(struct tcon_context *conn)
-{
- default_vfs_ops.disconnect(conn);
-}
-
-static SMB_BIG_UINT fake_perms_disk_free(struct tcon_context *conn, const char *path,
- BOOL small_query, SMB_BIG_UINT *bsize,
- SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
-{
- return default_vfs_ops.disk_free(conn, path, small_query, bsize,
- dfree, dsize);
-}
-
-static DIR *fake_perms_opendir(struct tcon_context *conn, const char *fname)
-{
- return default_vfs_ops.opendir(conn, fname);
-}
-
-static struct dirent *fake_perms_readdir(struct tcon_context *conn, DIR *dirp)
-{
- return default_vfs_ops.readdir(conn, dirp);
-}
-
-static int fake_perms_mkdir(struct tcon_context *conn, const char *path, mode_t mode)
-{
- return default_vfs_ops.mkdir(conn, path, mode);
-}
-
-static int fake_perms_rmdir(struct tcon_context *conn, const char *path)
-{
- return default_vfs_ops.rmdir(conn, path);
-}
-
-static int fake_perms_closedir(struct tcon_context *conn, DIR *dir)
-{
- return default_vfs_ops.closedir(conn, dir);
-}
-
-static int fake_perms_open(struct tcon_context *conn, const char *fname, int flags, mode_t mode)
-{
- return default_vfs_ops.open(conn, fname, flags, mode);
-}
-
-static int fake_perms_close(struct files_struct *fsp, int fd)
-{
- return default_vfs_ops.close(fsp, fd);
-}
-
-static ssize_t fake_perms_read(struct files_struct *fsp, int fd, void *data, size_t n)
-{
- return default_vfs_ops.read(fsp, fd, data, n);
-}
-
-static ssize_t fake_perms_write(struct files_struct *fsp, int fd, const void *data, size_t n)
-{
- return default_vfs_ops.write(fsp, fd, data, n);
-}
-
-static SMB_OFF_T fake_perms_lseek(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
-{
- return default_vfs_ops.lseek(fsp, filedes, offset, whence);
-}
-
-static int fake_perms_rename(struct tcon_context *conn, const char *old, const char *new)
-{
- return default_vfs_ops.rename(conn, old, new);
-}
-
-static int fake_perms_fsync(struct files_struct *fsp, int fd)
-{
- return default_vfs_ops.fsync(fsp, fd);
-}
-
-static int fake_perms_stat(struct tcon_context *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
-{
- int ret = default_vfs_ops.stat(conn, fname, sbuf);
- extern struct current_user current_user;
-
- if (S_ISDIR(sbuf->st_mode)) {
- sbuf->st_mode = S_IFDIR | S_IRWXU;
- } else {
- sbuf->st_mode = S_IRWXU;
- }
- sbuf->st_uid = current_user.uid;
- sbuf->st_gid = current_user.gid;
- return ret;
-}
-
-static int fake_perms_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
-{
- return default_vfs_ops.fstat(fsp, fd, sbuf);
-}
-
-static int fake_perms_lstat(struct tcon_context *conn, const char *path, SMB_STRUCT_STAT *sbuf)
-{
- return default_vfs_ops.lstat(conn, path, sbuf);
-}
-
-static int fake_perms_unlink(struct tcon_context *conn, const char *path)
-{
- return default_vfs_ops.unlink(conn, path);
-}
-
-static int fake_perms_chmod(struct tcon_context *conn, const char *path, mode_t mode)
-{
- return default_vfs_ops.chmod(conn, path, mode);
-}
-
-static int fake_perms_fchmod(struct files_struct *fsp, int fd, mode_t mode)
-{
- return default_vfs_ops.fchmod(fsp, fd, mode);
-}
-
-static int fake_perms_chown(struct tcon_context *conn, const char *path, uid_t uid, gid_t gid)
-{
- return default_vfs_ops.chown(conn, path, uid, gid);
-}
-
-static int fake_perms_fchown(struct files_struct *fsp, int fd, uid_t uid, gid_t gid)
-{
- return default_vfs_ops.fchown(fsp, fd, uid, gid);
-}
-
-static int fake_perms_chdir(struct tcon_context *conn, const char *path)
-{
- return default_vfs_ops.chdir(conn, path);
-}
-
-static char *fake_perms_getwd(struct tcon_context *conn, char *buf)
-{
- return default_vfs_ops.getwd(conn, buf);
-}
-
-static int fake_perms_utime(struct tcon_context *conn, const char *path, struct utimbuf *times)
-{
- return default_vfs_ops.utime(conn, path, times);
-}
-
-static int fake_perms_ftruncate(struct files_struct *fsp, int fd, SMB_OFF_T offset)
-{
- return default_vfs_ops.ftruncate(fsp, fd, offset);
-}
-
-static BOOL fake_perms_lock(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
-{
- return default_vfs_ops.lock(fsp, fd, op, offset, count, type);
-}
-
-static BOOL fake_perms_symlink(struct tcon_context *conn, const char *oldpath, const char *newpath)
-{
- return default_vfs_ops.symlink(conn, oldpath, newpath);
-}
-
-static BOOL fake_perms_readlink(struct tcon_context *conn, const char *path, char *buf, size_t bufsiz)
-{
- return default_vfs_ops.readlink(conn, path, buf, bufsiz);
-}
-
-static int fake_perms_link(struct tcon_context *conn, const char *oldpath, const char *newpath)
-{
- return default_vfs_ops.link(conn, oldpath, newpath);
-}
-
-static int fake_perms_mknod(struct tcon_context *conn, const char *path, mode_t mode, SMB_DEV_T dev)
-{
- return default_vfs_ops.mknod(conn, path, mode, dev);
-}
-
-static char *fake_perms_realpath(struct tcon_context *conn, const char *path, char *resolved_path)
-{
- return default_vfs_ops.realpath(conn, path, resolved_path);
-}
-
-static size_t fake_perms_fget_nt_acl(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc)
-{
- return default_vfs_ops.fget_nt_acl(fsp, fd, ppdesc);
-}
-
-static size_t fake_perms_get_nt_acl(struct files_struct *fsp, const char *name, struct security_descriptor_info **ppdesc)
-{
- return default_vfs_ops.get_nt_acl(fsp, name, ppdesc);
-}
-
-static BOOL fake_perms_fset_nt_acl(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd)
-{
- return default_vfs_ops.fset_nt_acl(fsp, fd, security_info_sent, psd);
-}
-
-static BOOL fake_perms_set_nt_acl(struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd)
-{
- return default_vfs_ops.set_nt_acl(fsp, name, security_info_sent, psd);
-}
-
-static BOOL fake_perms_chmod_acl(struct tcon_context *conn, const char *name, mode_t mode)
-{
- return default_vfs_ops.chmod_acl(conn, name, mode);
-}
-
-static BOOL fake_perms_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
-{
- return default_vfs_ops.fchmod_acl(fsp, fd, mode);
-}
-
-static int fake_perms_sys_acl_get_entry(struct tcon_context *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
-{
- return default_vfs_ops.sys_acl_get_entry(conn, theacl, entry_id, entry_p);
-}
-
-static int fake_perms_sys_acl_get_tag_type(struct tcon_context *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
-{
- return default_vfs_ops.sys_acl_get_tag_type(conn, entry_d, tag_type_p);
-}
-
-static int fake_perms_sys_acl_get_permset(struct tcon_context *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
-{
- return default_vfs_ops.sys_acl_get_permset(conn, entry_d, permset_p);
-}
-
-static void *fake_perms_sys_acl_get_qualifier(struct tcon_context *conn, SMB_ACL_ENTRY_T entry_d)
-{
- return default_vfs_ops.sys_acl_get_qualifier(conn, entry_d);
-}
-
-static SMB_ACL_T fake_perms_sys_acl_get_file(struct tcon_context *conn, const char *path_p, SMB_ACL_TYPE_T type)
-{
- return default_vfs_ops.sys_acl_get_file(conn, path_p, type);
-}
-
-static SMB_ACL_T fake_perms_sys_acl_get_fd(struct files_struct *fsp, int fd)
-{
- return default_vfs_ops.sys_acl_get_fd(fsp, fd);
-}
-
-static int fake_perms_sys_acl_clear_perms(struct tcon_context *conn, SMB_ACL_PERMSET_T permset)
-{
- return default_vfs_ops.sys_acl_clear_perms(conn, permset);
-}
-
-static int fake_perms_sys_acl_add_perm(struct tcon_context *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
-{
- return default_vfs_ops.sys_acl_add_perm(conn, permset, perm);
-}
-
-static char *fake_perms_sys_acl_to_text(struct tcon_context *conn, SMB_ACL_T theacl, ssize_t *plen)
-{
- return default_vfs_ops.sys_acl_to_text(conn, theacl, plen);
-}
-
-static SMB_ACL_T fake_perms_sys_acl_init(struct tcon_context *conn, int count)
-{
- return default_vfs_ops.sys_acl_init(conn, count);
-}
-
-static int fake_perms_sys_acl_create_entry(struct tcon_context *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
-{
- return default_vfs_ops.sys_acl_create_entry(conn, pacl, pentry);
-}
-
-static int fake_perms_sys_acl_set_tag_type(struct tcon_context *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
-{
- return default_vfs_ops.sys_acl_set_tag_type(conn, entry, tagtype);
-}
-
-static int fake_perms_sys_acl_set_qualifier(struct tcon_context *conn, SMB_ACL_ENTRY_T entry, void *qual)
-{
- return default_vfs_ops.sys_acl_set_qualifier(conn, entry, qual);
-}
-
-static int fake_perms_sys_acl_set_permset(struct tcon_context *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
-{
- return default_vfs_ops.sys_acl_set_permset(conn, entry, permset);
-}
-
-static int fake_perms_sys_acl_valid(struct tcon_context *conn, SMB_ACL_T theacl )
-{
- return default_vfs_ops.sys_acl_valid(conn, theacl );
-}
-
-static int fake_perms_sys_acl_set_file(struct tcon_context *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
-{
- return default_vfs_ops.sys_acl_set_file(conn, name, acltype, theacl);
-}
-
-static int fake_perms_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl)
-{
- return default_vfs_ops.sys_acl_set_fd(fsp, fd, theacl);
-}
-
-static int fake_perms_sys_acl_delete_def_file(struct tcon_context *conn, const char *path)
-{
- return default_vfs_ops.sys_acl_delete_def_file(conn, path);
-}
-
-static int fake_perms_sys_acl_get_perm(struct tcon_context *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
-{
- return default_vfs_ops.sys_acl_get_perm(conn, permset, perm);
-}
-
-static int fake_perms_sys_acl_free_text(struct tcon_context *conn, char *text)
-{
- return default_vfs_ops.sys_acl_free_text(conn, text);
-}
-
-static int fake_perms_sys_acl_free_acl(struct tcon_context *conn, SMB_ACL_T posix_acl)
-{
- return default_vfs_ops.sys_acl_free_acl(conn, posix_acl);
-}
-
-static int fake_perms_sys_acl_free_qualifier(struct tcon_context *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
-{
- return default_vfs_ops.sys_acl_free_qualifier(conn, qualifier, tagtype);
-}
-
-
-/* VFS operations structure */
-
-static vfs_op_tuple fake_perms_ops[] = {
-
- /* Disk operations */
-
- {fake_perms_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_disk_free, SMB_VFS_OP_DISK_FREE, SMB_VFS_LAYER_TRANSPARENT},
-
- /* Directory operations */
-
- {fake_perms_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_readdir, SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_closedir, SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_TRANSPARENT},
-
- /* File operations */
-
- {fake_perms_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_read, SMB_VFS_OP_READ, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_write, SMB_VFS_OP_WRITE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_lseek, SMB_VFS_OP_LSEEK, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_fsync, SMB_VFS_OP_FSYNC, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_stat, SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_fstat, SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_lstat, SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_chown, SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_fchown, SMB_VFS_OP_FCHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_chdir, SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_getwd, SMB_VFS_OP_GETWD, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_utime, SMB_VFS_OP_UTIME, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_ftruncate, SMB_VFS_OP_FTRUNCATE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_lock, SMB_VFS_OP_LOCK, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_symlink, SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_readlink, SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_link, SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_mknod, SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_realpath, SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT},
-
- /* NT File ACL operations */
-
- {fake_perms_fget_nt_acl, SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_get_nt_acl, SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_fset_nt_acl, SMB_VFS_OP_FSET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_set_nt_acl, SMB_VFS_OP_SET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- /* POSIX ACL operations */
-
- {fake_perms_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- {fake_perms_sys_acl_get_entry, SMB_VFS_OP_SYS_ACL_GET_ENTRY, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_tag_type, SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_permset, SMB_VFS_OP_SYS_ACL_GET_PERMSET, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_qualifier, SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_file, SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_fd, SMB_VFS_OP_SYS_ACL_GET_FD, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_clear_perms, SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_add_perm, SMB_VFS_OP_SYS_ACL_ADD_PERM, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_to_text, SMB_VFS_OP_SYS_ACL_TO_TEXT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_init, SMB_VFS_OP_SYS_ACL_INIT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_create_entry, SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_set_tag_type, SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_set_qualifier, SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_set_permset, SMB_VFS_OP_SYS_ACL_SET_PERMSET, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_valid, SMB_VFS_OP_SYS_ACL_VALID, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_set_file, SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_set_fd, SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_delete_def_file, SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_get_perm, SMB_VFS_OP_SYS_ACL_GET_PERM, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_free_text, SMB_VFS_OP_SYS_ACL_FREE_TEXT, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_free_acl, SMB_VFS_OP_SYS_ACL_FREE_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {fake_perms_sys_acl_free_qualifier, SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-/* VFS initialisation - return initialized vfs_op_tuple array back to Samba */
-
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
-{
- DEBUG(3, ("Initialising default vfs hooks\n"));
-
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- /* Remember vfs_handle for further allocation and referencing of private
- information in vfs_handle->data
- */
- fake_perms_handle = vfs_handle;
- return fake_perms_ops;
-}
-
-/* VFS finalization function */
-void vfs_done(struct tcon_context *conn)
-{
- DEBUG(3, ("Finalizing default vfs hooks\n"));
-}
diff --git a/source4/modules/vfs_netatalk.c b/source4/modules/vfs_netatalk.c
deleted file mode 100644
index 0c1eb8d15e..0000000000
--- a/source4/modules/vfs_netatalk.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * AppleTalk VFS module for Samba-3.x
- *
- * Copyright (C) Alexei Kotovich, 2002
- *
- * 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 "config.h"
-#include <stdio.h>
-#include <sys/stat.h>
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <errno.h>
-#include <string.h>
-#include <includes.h>
-#include <vfs.h>
-
-#define APPLEDOUBLE ".AppleDouble"
-#define ADOUBLEMODE 0777
-
-/* atalk functions */
-
-static int atalk_build_paths(TALLOC_CTX *ctx, const char *path,
- const char *fname, char **adbl_path, char **orig_path,
- SMB_STRUCT_STAT *adbl_info, SMB_STRUCT_STAT *orig_info);
-
-static int atalk_unlink_file(const char *path);
-
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *atalk_handle;
-
-static int atalk_get_path_ptr(char *path)
-{
- int i = 0;
- int ptr = 0;
-
- for (i = 0; path[i]; i ++) {
- if (path[i] == '/')
- ptr = i;
- /* get out some 'spam';) from win32's file name */
- else if (path[i] == ':') {
- path[i] = '\0';
- break;
- }
- }
-
- return ptr;
-}
-
-static int atalk_build_paths(TALLOC_CTX *ctx, const char *path, const char *fname,
- char **adbl_path, char **orig_path,
- SMB_STRUCT_STAT *adbl_info, SMB_STRUCT_STAT *orig_info)
-{
- int ptr0 = 0;
- int ptr1 = 0;
- char *dname = 0;
- char *name = 0;
-
- if (!ctx || !path || !fname || !adbl_path || !orig_path ||
- !adbl_info || !orig_info)
- return -1;
-#if 0
- DEBUG(3, ("ATALK: PATH: %s[%s]\n", path, fname));
-#endif
- if (strstr(path, APPLEDOUBLE) || strstr(fname, APPLEDOUBLE)) {
- DEBUG(3, ("ATALK: path %s[%s] already contains %s\n", path, fname, APPLEDOUBLE));
- return -1;
- }
-
- if (fname[0] == '.') ptr0 ++;
- if (fname[1] == '/') ptr0 ++;
-
- *orig_path = talloc_asprintf(ctx, "%s/%s", path, &fname[ptr0]);
-
- /* get pointer to last '/' */
- ptr1 = atalk_get_path_ptr(*orig_path);
-
- sys_lstat(*orig_path, orig_info);
-
- if (S_ISDIR(orig_info->st_mode)) {
- *adbl_path = talloc_asprintf(ctx, "%s/%s/%s/",
- path, &fname[ptr0], APPLEDOUBLE);
- } else {
- dname = talloc_strdup(ctx, *orig_path);
- dname[ptr1] = '\0';
- name = *orig_path;
- *adbl_path = talloc_asprintf(ctx, "%s/%s/%s",
- dname, APPLEDOUBLE, &name[ptr1 + 1]);
- }
-#if 0
- DEBUG(3, ("ATALK: DEBUG:\n%s\n%s\n", *orig_path, *adbl_path));
-#endif
- sys_lstat(*adbl_path, adbl_info);
- return 0;
-}
-
-static int atalk_unlink_file(const char *path)
-{
- int ret = 0;
-
- become_root();
- ret = unlink(path);
- unbecome_root();
-
- return ret;
-}
-
-static void atalk_add_to_list(name_compare_entry **list)
-{
- int i, count = 0;
- name_compare_entry *new_list = 0;
- name_compare_entry *cur_list = 0;
-
- cur_list = *list;
-
- if (cur_list) {
- for (i = 0, count = 0; cur_list[i].name; i ++, count ++) {
- if (strstr(cur_list[i].name, APPLEDOUBLE))
- return;
- }
- }
-
- if (!(new_list = calloc(1,
- (count == 0 ? 1 : count + 1) * sizeof(name_compare_entry))))
- return;
-
- for (i = 0; i < count; i ++) {
- new_list[i].name = strdup(cur_list[i].name);
- new_list[i].is_wild = cur_list[i].is_wild;
- }
-
- new_list[i].name = strdup(APPLEDOUBLE);
- new_list[i].is_wild = False;
-
- free_namearray(*list);
-
- *list = new_list;
- new_list = 0;
- cur_list = 0;
-}
-
-static void atalk_rrmdir(TALLOC_CTX *ctx, char *path)
-{
- char *dpath;
- struct dirent *dent = 0;
- DIR *dir;
-
- if (!path) return;
-
- dir = opendir(path);
- if (!dir) return;
-
- while (NULL != (dent = readdir(dir))) {
- if (strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0)
- continue;
- if (!(dpath = talloc_asprintf(ctx, "%s/%s",
- path, dent->d_name)))
- continue;
- atalk_unlink_file(dpath);
- }
-
- closedir(dir);
-}
-
-/* Disk operations */
-
-/* Directory operations */
-
-DIR *atalk_opendir(struct tcon_context *conn, const char *fname)
-{
- DIR *ret = 0;
-
- ret = default_vfs_ops.opendir(conn, fname);
-
- /*
- * when we try to perform delete operation upon file which has fork
- * in ./.AppleDouble and this directory wasn't hidden by Samba,
- * MS Windows explorer causes the error: "Cannot find the specified file"
- * There is some workaround to avoid this situation, i.e. if
- * connection has not .AppleDouble entry in either veto or hide
- * list then it would be nice to add one.
- */
-
- atalk_add_to_list(&conn->hide_list);
- atalk_add_to_list(&conn->veto_list);
-
- return ret;
-}
-
-static int atalk_rmdir(struct tcon_context *conn, const char *path)
-{
- BOOL add = False;
- TALLOC_CTX *ctx = 0;
- char *dpath;
-
- if (!conn || !conn->origpath || !path) goto exit_rmdir;
-
- /* due to there is no way to change bDeleteVetoFiles variable
- * from this module, gotta use talloc stuff..
- */
-
- strstr(path, APPLEDOUBLE) ? (add = False) : (add = True);
-
- if (!(ctx = talloc_init("remove_directory")))
- goto exit_rmdir;
-
- if (!(dpath = talloc_asprintf(ctx, "%s/%s%s",
- conn->origpath, path, add ? "/"APPLEDOUBLE : "")))
- goto exit_rmdir;
-
- atalk_rrmdir(ctx, dpath);
-
-exit_rmdir:
- talloc_destroy(ctx);
- return default_vfs_ops.rmdir(conn, path);
-}
-
-/* File operations */
-
-static int atalk_rename(struct tcon_context *conn, const char *old, const char *new)
-{
- int ret = 0;
- char *adbl_path = 0;
- char *orig_path = 0;
- SMB_STRUCT_STAT adbl_info;
- SMB_STRUCT_STAT orig_info;
- TALLOC_CTX *ctx;
-
- ret = default_vfs_ops.rename(conn, old, new);
-
- if (!conn || !old) return ret;
-
- if (!(ctx = talloc_init("rename_file")))
- return ret;
-
- if (atalk_build_paths(ctx, conn->origpath, old, &adbl_path, &orig_path,
- &adbl_info, &orig_info) != 0)
- return ret;
-
- if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
- goto exit_rename;
- }
-
- atalk_unlink_file(adbl_path);
-
-exit_rename:
- talloc_destroy(ctx);
- return ret;
-}
-
-static int atalk_unlink(struct tcon_context *conn, const char *path)
-{
- int ret = 0, i;
- char *adbl_path = 0;
- char *orig_path = 0;
- SMB_STRUCT_STAT adbl_info;
- SMB_STRUCT_STAT orig_info;
- TALLOC_CTX *ctx;
-
- ret = default_vfs_ops.unlink(conn, path);
-
- if (!conn || !path) return ret;
-
- /* no .AppleDouble sync if veto or hide list is empty,
- * otherwise "Cannot find the specified file" error will be caused
- */
-
- if (!conn->veto_list) return ret;
- if (!conn->hide_list) return ret;
-
- for (i = 0; conn->veto_list[i].name; i ++) {
- if (strstr(conn->veto_list[i].name, APPLEDOUBLE))
- break;
- }
-
- if (!conn->veto_list[i].name) {
- for (i = 0; conn->hide_list[i].name; i ++) {
- if (strstr(conn->hide_list[i].name, APPLEDOUBLE))
- break;
- else {
- DEBUG(3, ("ATALK: %s is not hidden, skipped..\n",
- APPLEDOUBLE));
- return ret;
- }
- }
- }
-
- if (!(ctx = talloc_init("unlink_file")))
- return ret;
-
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
- &adbl_info, &orig_info) != 0)
- return ret;
-
- if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
- goto exit_unlink;
- }
-
- atalk_unlink_file(adbl_path);
-
-exit_unlink:
- talloc_destroy(ctx);
- return ret;
-}
-
-static int atalk_chmod(struct tcon_context *conn, const char *path, mode_t mode)
-{
- int ret = 0;
- char *adbl_path = 0;
- char *orig_path = 0;
- SMB_STRUCT_STAT adbl_info;
- SMB_STRUCT_STAT orig_info;
- TALLOC_CTX *ctx;
-
- ret = default_vfs_ops.chmod(conn, path, mode);
-
- if (!conn || !path) return ret;
-
- if (!(ctx = talloc_init("chmod_file")))
- return ret;
-
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
- &adbl_info, &orig_info) != 0)
- return ret;
-
- if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
- goto exit_chmod;
- }
-
- chmod(adbl_path, ADOUBLEMODE);
-
-exit_chmod:
- talloc_destroy(ctx);
- return ret;
-}
-
-static int atalk_chown(struct tcon_context *conn, const char *path, uid_t uid, gid_t gid)
-{
- int ret = 0;
- char *adbl_path = 0;
- char *orig_path = 0;
- SMB_STRUCT_STAT adbl_info;
- SMB_STRUCT_STAT orig_info;
- TALLOC_CTX *ctx;
-
- ret = default_vfs_ops.chown(conn, path, uid, gid);
-
- if (!conn || !path) return ret;
-
- if (!(ctx = talloc_init("chown_file")))
- return ret;
-
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
- &adbl_info, &orig_info) != 0)
- return ret;
-
- if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
- goto exit_chown;
- }
-
- chown(adbl_path, uid, gid);
-
-exit_chown:
- talloc_destroy(ctx);
- return ret;
-}
-
-static vfs_op_tuple atalk_ops[] = {
-
- /* Directory operations */
-
- {atalk_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
-
- /* File operations */
-
- {atalk_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {atalk_chown, SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
-
- /* Finish VFS operations definition */
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
-{
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- atalk_handle = vfs_handle;
-
- DEBUG(3, ("ATALK: vfs module loaded\n"));
- return atalk_ops;
-}
-
-/* VFS finalization function. */
-void vfs_done(struct tcon_context *conn)
-{
- DEBUG(3, ("ATALK: vfs module unloaded\n"));
-}
diff --git a/source4/modules/vfs_recycle.c b/source4/modules/vfs_recycle.c
deleted file mode 100644
index 2a017aca04..0000000000
--- a/source4/modules/vfs_recycle.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * Recycle bin VFS module for Samba.
- *
- * Copyright (C) 2001, Brandon Stone, Amherst College, <bbstone@amherst.edu>.
- * Copyright (C) 2002, Jeremy Allison - modified to make a VFS module.
- * Copyright (C) 2002, Alexander Bokovoy - cascaded VFS adoption,
- * Copyright (C) 2002, Juergen Hasch - added some options.
- * Copyright (C) 2002, Simo Sorce
- *
- * 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"
-
-#define ALLOC_CHECK(ptr, label) do { if ((ptr) == NULL) { DEBUG(0, ("recycle.bin: out of memory!\n")); errno = ENOMEM; goto label; } } while(0)
-
-static int vfs_recycle_debug_level = DBGC_VFS;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS vfs_recycle_debug_level
-
-static const char *delimiter = "|"; /* delimiter for options */
-
-/* One per connection */
-
-typedef struct recycle_bin_struct
-{
- TALLOC_CTX *mem_ctx;
- char *repository; /* name of the recycle bin directory */
- BOOL keep_dir_tree; /* keep directory structure of deleted file in recycle bin */
- BOOL versions; /* create versions of deleted files with identical name */
- BOOL touch; /* touch access date of deleted file */
- char *exclude; /* which files to exclude */
- char *exclude_dir; /* which directories to exclude */
- char *noversions; /* which files to exclude from versioning */
- SMB_OFF_T maxsize; /* maximum file size to be saved */
-} recycle_bin_struct;
-
-typedef struct recycle_bin_connections {
- int conn;
- recycle_bin_struct *data;
- struct recycle_bin_connections *next;
-} recycle_bin_connections;
-
-typedef struct recycle_bin_private_data {
- TALLOC_CTX *mem_ctx;
- recycle_bin_connections *conns;
-} recycle_bin_private_data;
-
-struct smb_vfs_handle_struct *recycle_bin_private_handle;
-
-/* VFS operations */
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-
-static int recycle_connect(struct tcon_context *conn, const char *service, const char *user);
-static void recycle_disconnect(struct tcon_context *conn);
-static int recycle_unlink(struct tcon_context *, const char *);
-
-#define VFS_OP(x) ((void *) x)
-
-static vfs_op_tuple recycle_ops[] = {
-
- /* Disk operations */
- {VFS_OP(recycle_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {VFS_OP(recycle_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
-
- /* File operations */
- {VFS_OP(recycle_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-/**
- * VFS initialisation function.
- *
- * @retval initialised vfs_op_tuple array
- **/
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
-{
- TALLOC_CTX *mem_ctx = NULL;
-
- DEBUG(10, ("Initializing VFS module recycle\n"));
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
- vfs_recycle_debug_level = debug_add_class("vfs_recycle_bin");
- if (vfs_recycle_debug_level == -1) {
- vfs_recycle_debug_level = DBGC_VFS;
- DEBUG(0, ("vfs_recycle: Couldn't register custom debugging class!\n"));
- } else {
- DEBUG(0, ("vfs_recycle: Debug class number of 'vfs_recycle': %d\n", vfs_recycle_debug_level));
- }
-
- recycle_bin_private_handle = vfs_handle;
- if (!(mem_ctx = talloc_init("recycle bin data"))) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- return NULL;
- }
-
- recycle_bin_private_handle->data = talloc(mem_ctx, sizeof(recycle_bin_private_data));
- if (recycle_bin_private_handle->data == NULL) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- return NULL;
- }
- ((recycle_bin_private_data *)(recycle_bin_private_handle->data))->mem_ctx = mem_ctx;
- ((recycle_bin_private_data *)(recycle_bin_private_handle->data))->conns = NULL;
-
- return recycle_ops;
-}
-
-/**
- * VFS finalization function.
- *
- **/
-void vfs_done(void)
-{
- recycle_bin_private_data *recdata;
- recycle_bin_connections *recconn;
-
- DEBUG(10, ("Unloading/Cleaning VFS module recycle bin\n"));
-
- if (recycle_bin_private_handle)
- recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
- else {
- DEBUG(0, ("Recycle bin not initialized!\n"));
- return;
- }
-
- if (recdata) {
- if (recdata->conns) {
- recconn = recdata->conns;
- while (recconn) {
- talloc_destroy(recconn->data->mem_ctx);
- recconn = recconn->next;
- }
- }
- if (recdata->mem_ctx) {
- talloc_destroy(recdata->mem_ctx);
- }
- recdata = NULL;
- }
-}
-
-static int recycle_connect(struct tcon_context *conn, const char *service, const char *user)
-{
- TALLOC_CTX *ctx = NULL;
- recycle_bin_struct *recbin;
- recycle_bin_connections *recconn;
- recycle_bin_connections *recconnbase;
- recycle_bin_private_data *recdata;
- char *tmp_str;
-
- DEBUG(10, ("Called for service %s (%d) as user %s\n", service, SNUM(conn), user));
-
- if (recycle_bin_private_handle)
- recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
- else {
- DEBUG(0, ("Recycle bin not initialized!\n"));
- return -1;
- }
-
- if (!(ctx = talloc_init("recycle bin connection"))) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- return -1;
- }
-
- recbin = talloc(ctx, sizeof(recycle_bin_struct));
- if (recbin == NULL) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- return -1;
- }
- recbin->mem_ctx = ctx;
-
- /* Set defaults */
- recbin->repository = talloc_strdup(recbin->mem_ctx, ".recycle");
- ALLOC_CHECK(recbin->repository, error);
- recbin->keep_dir_tree = False;
- recbin->versions = False;
- recbin->touch = False;
- recbin->exclude = "";
- recbin->exclude_dir = "";
- recbin->noversions = "";
- recbin->maxsize = 0;
-
- /* parse configuration options */
- if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "repository")) != NULL) {
- recbin->repository = talloc_sub_conn(recbin->mem_ctx, conn, tmp_str);
- ALLOC_CHECK(recbin->repository, error);
- trim_string(recbin->repository, "/", "/");
- DEBUG(5, ("recycle.bin: repository = %s\n", recbin->repository));
- }
-
- recbin->keep_dir_tree = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "keeptree", False);
- DEBUG(5, ("recycle.bin: keeptree = %d\n", recbin->keep_dir_tree));
-
- recbin->versions = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "versions", False);
- DEBUG(5, ("recycle.bin: versions = %d\n", recbin->versions));
-
- recbin->touch = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "touch", False);
- DEBUG(5, ("recycle.bin: touch = %d\n", recbin->touch));
-
- recbin->maxsize = lp_parm_ulong(SNUM(conn), "vfs_recycle_bin", "maxsize");
- if (recbin->maxsize == 0) {
- recbin->maxsize = -1;
- DEBUG(5, ("recycle.bin: maxsize = -infinite-\n"));
- } else {
- DEBUG(5, ("recycle.bin: maxsize = %ld\n", (long int)recbin->maxsize));
- }
-
- if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "exclude")) != NULL) {
- recbin->exclude = talloc_strdup(recbin->mem_ctx, tmp_str);
- ALLOC_CHECK(recbin->exclude, error);
- DEBUG(5, ("recycle.bin: exclude = %s\n", recbin->exclude));
- }
- if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "exclude_dir")) != NULL) {
- recbin->exclude_dir = talloc_strdup(recbin->mem_ctx, tmp_str);
- ALLOC_CHECK(recbin->exclude_dir, error);
- DEBUG(5, ("recycle.bin: exclude_dir = %s\n", recbin->exclude_dir));
- }
- if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "noversions")) != NULL) {
- recbin->noversions = talloc_strdup(recbin->mem_ctx, tmp_str);
- ALLOC_CHECK(recbin->noversions, error);
- DEBUG(5, ("recycle.bin: noversions = %s\n", recbin->noversions));
- }
-
- recconn = talloc(recdata->mem_ctx, sizeof(recycle_bin_connections));
- if (recconn == NULL) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- goto error;
- }
- recconn->conn = SNUM(conn);
- recconn->data = recbin;
- recconn->next = NULL;
- if (recdata->conns) {
- recconnbase = recdata->conns;
- while (recconnbase->next != NULL) recconnbase = recconnbase->next;
- recconnbase->next = recconn;
- } else {
- recdata->conns = recconn;
- }
- return default_vfs_ops.connect(conn, service, user);
-
-error:
- talloc_destroy(ctx);
- return -1;
-}
-
-static void recycle_disconnect(struct tcon_context *conn)
-{
- recycle_bin_private_data *recdata;
- recycle_bin_connections *recconn;
-
- DEBUG(10, ("Disconnecting VFS module recycle bin\n"));
-
- if (recycle_bin_private_handle)
- recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
- else {
- DEBUG(0, ("Recycle bin not initialized!\n"));
- return;
- }
-
- if (recdata) {
- if (recdata->conns) {
- if (recdata->conns->conn == SNUM(conn)) {
- talloc_destroy(recdata->conns->data->mem_ctx);
- recdata->conns = recdata->conns->next;
- } else {
- recconn = recdata->conns;
- while (recconn->next) {
- if (recconn->next->conn == SNUM(conn)) {
- talloc_destroy(recconn->next->data->mem_ctx);
- recconn->next = recconn->next->next;
- break;
- }
- recconn = recconn->next;
- }
- }
- }
- }
- default_vfs_ops.disconnect(conn);
-}
-
-static BOOL recycle_directory_exist(struct tcon_context *conn, const char *dname)
-{
- SMB_STRUCT_STAT st;
-
- if (default_vfs_ops.stat(conn, dname, &st) == 0) {
- if (S_ISDIR(st.st_mode)) {
- return True;
- }
- }
-
- return False;
-}
-
-static BOOL recycle_file_exist(struct tcon_context *conn, const char *fname)
-{
- SMB_STRUCT_STAT st;
-
- if (default_vfs_ops.stat(conn, fname, &st) == 0) {
- if (S_ISREG(st.st_mode)) {
- return True;
- }
- }
-
- return False;
-}
-
-/**
- * Return file size
- * @param conn connection
- * @param fname file name
- * @return size in bytes
- **/
-static SMB_OFF_T recycle_get_file_size(struct tcon_context *conn, const char *fname)
-{
- SMB_STRUCT_STAT st;
- if (default_vfs_ops.stat(conn, fname, &st) != 0) {
- DEBUG(0,("recycle.bin: stat for %s returned %s\n", fname, strerror(errno)));
- return (SMB_OFF_T)0;
- }
- return(st.st_size);
-}
-
-/**
- * Create directory tree
- * @param conn connection
- * @param dname Directory tree to be created
- * @return Returns True for success
- **/
-static BOOL recycle_create_dir(struct tcon_context *conn, const char *dname)
-{
- int len;
- mode_t mode;
- char *new_dir = NULL;
- char *tmp_str = NULL;
- char *token;
- char *tok_str;
- BOOL ret = False;
-
- mode = S_IREAD | S_IWRITE | S_IEXEC;
-
- tmp_str = strdup(dname);
- ALLOC_CHECK(tmp_str, done);
- tok_str = tmp_str;
-
- len = strlen(dname);
- new_dir = (char *)malloc(len + 1);
- ALLOC_CHECK(new_dir, done);
- *new_dir = '\0';
-
- /* Create directory tree if neccessary */
- for(token = strtok(tok_str, "/"); token; token = strtok(NULL, "/")) {
- safe_strcat(new_dir, token, len);
- if (recycle_directory_exist(conn, new_dir))
- DEBUG(10, ("recycle.bin: dir %s already exists\n", new_dir));
- else {
- DEBUG(5, ("recycle.bin: creating new dir %s\n", new_dir));
- if (default_vfs_ops.mkdir(conn, new_dir, mode) != 0) {
- DEBUG(1,("recycle.bin: mkdir failed for %s with error: %s\n", new_dir, strerror(errno)));
- ret = False;
- goto done;
- }
- }
- safe_strcat(new_dir, "/", len);
- }
-
- ret = True;
-done:
- SAFE_FREE(tmp_str);
- SAFE_FREE(new_dir);
- return ret;
-}
-
-/**
- * Check if needle is contained exactly in haystack
- * @param haystack list of parameters separated by delimimiter character
- * @param needle string to be matched exactly to haystack
- * @return True if found
- **/
-static BOOL checkparam(const char *haystack, const char *needle)
-{
- char *token;
- char *tok_str;
- char *tmp_str;
- BOOL ret = False;
-
- if (haystack == NULL || strlen(haystack) == 0 || needle == NULL || strlen(needle) == 0) {
- return False;
- }
-
- tmp_str = strdup(haystack);
- ALLOC_CHECK(tmp_str, done);
- token = tok_str = tmp_str;
-
- for(token = strtok(tok_str, delimiter); token; token = strtok(NULL, delimiter)) {
- if(strcmp(token, needle) == 0) {
- ret = True;
- goto done;
- }
- }
-done:
- SAFE_FREE(tmp_str);
- return ret;
-}
-
-/**
- * Check if needle is contained in haystack, * and ? patterns are resolved
- * @param haystack list of parameters separated by delimimiter character
- * @param needle string to be matched exectly to haystack including pattern matching
- * @return True if found
- **/
-static BOOL matchparam(const char *haystack, const char *needle)
-{
- char *token;
- char *tok_str;
- char *tmp_str;
- BOOL ret = False;
-
- if (haystack == NULL || strlen(haystack) == 0 || needle == NULL || strlen(needle) == 0) {
- return False;
- }
-
- tmp_str = strdup(haystack);
- ALLOC_CHECK(tmp_str, done);
- token = tok_str = tmp_str;
-
- for(token = strtok(tok_str, delimiter); token; token = strtok(NULL, delimiter)) {
- if (!unix_wild_match(token, needle)) {
- ret = True;
- goto done;
- }
- }
-done:
- SAFE_FREE(tmp_str);
- return ret;
-}
-
-/**
- * Touch access date
- **/
-static void recycle_touch(struct tcon_context *conn, const char *fname)
-{
- SMB_STRUCT_STAT st;
- struct utimbuf tb;
- time_t currtime;
-
- if (default_vfs_ops.stat(conn, fname, &st) != 0) {
- DEBUG(0,("recycle.bin: stat for %s returned %s\n", fname, strerror(errno)));
- return;
- }
- currtime = time(&currtime);
- tb.actime = currtime;
- tb.modtime = st.st_mtime;
-
- if (default_vfs_ops.utime(conn, fname, &tb) == -1 )
- DEBUG(0, ("recycle.bin: touching %s failed, reason = %s\n", fname, strerror(errno)));
- }
-
-/**
- * Check if file should be recycled
- **/
-static int recycle_unlink(struct tcon_context *conn, const char *file_name)
-{
- recycle_bin_private_data *recdata;
- recycle_bin_connections *recconn;
- recycle_bin_struct *recbin;
- char *path_name = NULL;
- char *temp_name = NULL;
- char *final_name = NULL;
- const char *base;
- int i;
-/* SMB_BIG_UINT dfree, dsize, bsize; */
- SMB_OFF_T file_size; /* space_avail; */
- BOOL exist;
- int rc = -1;
-
- recbin = NULL;
- if (recycle_bin_private_handle) {
- recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
- if (recdata) {
- if (recdata->conns) {
- recconn = recdata->conns;
- while (recconn && recconn->conn != SNUM(conn)) recconn = recconn->next;
- if (recconn != NULL) {
- recbin = recconn->data;
- }
- }
- }
- }
- if (recbin == NULL) {
- DEBUG(0, ("Recycle bin not initialized!\n"));
- rc = default_vfs_ops.unlink(conn, file_name);
- goto done;
- }
-
- if(!recbin->repository || *(recbin->repository) == '\0') {
- DEBUG(3, ("Recycle path not set, purging %s...\n", file_name));
- rc = default_vfs_ops.unlink(conn, file_name);
- goto done;
- }
-
- /* we don't recycle the recycle bin... */
- if (strncmp(file_name, recbin->repository, strlen(recbin->repository)) == 0) {
- DEBUG(3, ("File is within recycling bin, unlinking ...\n"));
- rc = default_vfs_ops.unlink(conn, file_name);
- goto done;
- }
-
- file_size = recycle_get_file_size(conn, file_name);
- /* it is wrong to purge filenames only because they are empty imho
- * --- simo
- *
- if(fsize == 0) {
- DEBUG(3, ("File %s is empty, purging...\n", file_name));
- rc = default_vfs_ops.unlink(conn,file_name);
- goto done;
- }
- */
-
- /* FIXME: this is wrong, we should check the hole size of the recycle bin is
- * not greater then maxsize, not the size of the single file, also it is better
- * to remove older files
- */
- if(recbin->maxsize > 0 && file_size > recbin->maxsize) {
- DEBUG(3, ("File %s exceeds maximum recycle size, purging... \n", file_name));
- rc = default_vfs_ops.unlink(conn, file_name);
- goto done;
- }
-
- /* FIXME: this is wrong: moving files with rename does not change the disk space
- * allocation
- *
- space_avail = default_vfs_ops.disk_free(conn, ".", True, &bsize, &dfree, &dsize) * 1024L;
- DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size));
- if(space_avail < file_size) {
- DEBUG(3, ("Not enough diskspace, purging file %s\n", file_name));
- rc = default_vfs_ops.unlink(conn, file_name);
- goto done;
- }
- */
-
- /* extract filename and path */
- path_name = (char *)malloc(PATH_MAX);
- ALLOC_CHECK(path_name, done);
- *path_name = '\0';
- safe_strcpy(path_name, file_name, PATH_MAX - 1);
- base = strrchr(path_name, '/');
- if (base == NULL) {
- base = file_name;
- safe_strcpy(path_name, "/", PATH_MAX - 1);
- }
- else {
- base++;
- }
-
- DEBUG(10, ("recycle.bin: fname = %s\n", file_name)); /* original filename with path */
- DEBUG(10, ("recycle.bin: fpath = %s\n", path_name)); /* original path */
- DEBUG(10, ("recycle.bin: base = %s\n", base)); /* filename without path */
-
- if (matchparam(recbin->exclude, base)) {
- DEBUG(3, ("recycle.bin: file %s is excluded \n", base));
- rc = default_vfs_ops.unlink(conn, file_name);
- goto done;
- }
-
- /* FIXME: this check will fail if we have more than one level of directories,
- * we shoud check for every level 1, 1/2, 1/2/3, 1/2/3/4 ....
- * ---simo
- */
- if (checkparam(recbin->exclude_dir, path_name)) {
- DEBUG(3, ("recycle.bin: directory %s is excluded \n", path_name));
- rc = default_vfs_ops.unlink(conn, file_name);
- goto done;
- }
-
- temp_name = (char *)strdup(recbin->repository);
- ALLOC_CHECK(temp_name, done);
-
- /* see if we need to recreate the original directory structure in the recycle bin */
- if (recbin->keep_dir_tree == True) {
- safe_strcat(temp_name, "/", PATH_MAX - 1);
- safe_strcat(temp_name, path_name, PATH_MAX - 1);
- }
-
- exist = recycle_directory_exist(conn, temp_name);
- if (exist) {
- DEBUG(10, ("recycle.bin: Directory already exists\n"));
- } else {
- DEBUG(10, ("recycle.bin: Creating directory %s\n", temp_name));
- if (recycle_create_dir(conn, temp_name) == False) {
- DEBUG(3, ("Could not create directory, purging %s...\n", file_name));
- rc = default_vfs_ops.unlink(conn, file_name);
- goto done;
- }
- }
-
- final_name = NULL;
- asprintf(&final_name, "%s/%s", temp_name, base);
- ALLOC_CHECK(final_name, done);
- DEBUG(10, ("recycle.bin: recycled file name%s\n", temp_name)); /* new filename with path */
-
- /* check if we should delete file from recycle bin */
- if (recycle_file_exist(conn, final_name)) {
- if (recbin->versions == False || matchparam(recbin->noversions, base) == True) {
- DEBUG(3, ("recycle.bin: Removing old file %s from recycle bin\n", final_name));
- if (default_vfs_ops.unlink(conn, final_name) != 0) {
- DEBUG(1, ("recycle.bin: Error deleting old file: %s\n", strerror(errno)));
- }
- }
- }
-
- /* rename file we move to recycle bin */
- i = 1;
- while (recycle_file_exist(conn, final_name)) {
- snprintf(final_name, PATH_MAX, "%s/Copy #%d of %s", temp_name, i++, base);
- }
-
- DEBUG(10, ("recycle.bin: Moving %s to %s\n", file_name, final_name));
- rc = default_vfs_ops.rename(conn, file_name, final_name);
- if (rc != 0) {
- DEBUG(3, ("recycle.bin: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name));
- rc = default_vfs_ops.unlink(conn, file_name);
- goto done;
- }
-
- /* touch access date of moved file */
- if (recbin->touch == True )
- recycle_touch(conn, final_name);
-
-done:
- SAFE_FREE(path_name);
- SAFE_FREE(temp_name);
- SAFE_FREE(final_name);
- return rc;
-}
diff --git a/source4/modules/xml.c b/source4/modules/xml.c
deleted file mode 100644
index ead3e3a874..0000000000
--- a/source4/modules/xml.c
+++ /dev/null
@@ -1,575 +0,0 @@
-
-/*
- * XML password backend for samba
- * Copyright (C) Jelmer Vernooij 2002
- * Some parts based on the libxml gjobread example by Daniel Veillard
- *
- * 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.
- */
-
-/* FIXME:
- * - Support stdin input by using '-'
- * - Be faster. Don't rewrite the whole file when adding a user, but store it in the memory and save it when exiting. Requires changes to samba source.
- * - Gives the ability to read/write to standard input/output
- * - Do locking!
- * - Better names!
- */
-
-
-#define XML_URL "http://www.samba.org/ns"
-
-#include "includes.h"
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-
-static int xmlsam_debug_level = DBGC_ALL;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS xmlsam_debug_level
-
-static char * iota(int a) {
- static char tmp[10];
-
- snprintf(tmp, 9, "%d", a);
- return tmp;
-}
-
-BOOL parsePass(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SAM_ACCOUNT * u)
-{
- pstring temp;
-
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
- if (strcmp(cur->name, "crypt"))
- DEBUG(0, ("Unknown element %s\n", cur->name));
- else {
- if (!strcmp(xmlGetProp(cur, "type"), "nt")
- &&
- pdb_gethexpwd(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1), temp))
- pdb_set_nt_passwd(u, temp, PDB_SET);
- else if (!strcmp(xmlGetProp(cur, "type"), "lanman")
- &&
- pdb_gethexpwd(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1), temp))
- pdb_set_lanman_passwd(u, temp, PDB_SET);
- else
- DEBUG(0,
- ("Unknown crypt type: %s\n",
- xmlGetProp(cur, "type")));
- }
- cur = cur->next;
- }
- return True;
-}
-
-BOOL parseUser(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SAM_ACCOUNT * u)
-{
- char *tmp;
- DOM_SID sid;
-
- tmp = xmlGetProp(cur, "sid");
- if (tmp){
- string_to_sid(&sid, tmp);
- pdb_set_user_sid(u, &sid, PDB_SET);
- }
- tmp = xmlGetProp(cur, "uid");
- if (tmp)
- pdb_set_uid(u, atol(tmp), PDB_SET);
- pdb_set_username(u, xmlGetProp(cur, "name"), PDB_SET);
- /* We don't care what the top level element name is */
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
- if ((!strcmp(cur->name, "group")) && (cur->ns == ns)) {
- tmp = xmlGetProp(cur, "gid");
- if (tmp)
- pdb_set_gid(u, atol(tmp), PDB_SET);
- tmp = xmlGetProp(cur, "sid");
- if (tmp){
- string_to_sid(&sid, tmp);
- pdb_set_group_sid(u, &sid, PDB_SET);
- }
- }
-
- else if ((!strcmp(cur->name, "domain")) && (cur->ns == ns))
- pdb_set_domain(u,
- xmlNodeListGetString(doc, cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "fullname") && cur->ns == ns)
- pdb_set_fullname(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "nt_username") && cur->ns == ns)
- pdb_set_nt_username(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "logon_script") && cur->ns == ns)
- pdb_set_logon_script(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "profile_path") && cur->ns == ns)
- pdb_set_profile_path(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "logon_time") && cur->ns == ns)
- pdb_set_logon_time(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "logoff_time") && cur->ns == ns)
- pdb_set_logoff_time(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)),
- PDB_SET);
-
- else if (!strcmp(cur->name, "kickoff_time") && cur->ns == ns)
- pdb_set_kickoff_time(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)),
- PDB_SET);
-
- else if (!strcmp(cur->name, "logon_divs") && cur->ns == ns)
- pdb_set_logon_divs(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "hours_len") && cur->ns == ns)
- pdb_set_hours_len(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "unknown_3") && cur->ns == ns)
- pdb_set_unknown_3(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "unknown_5") && cur->ns == ns)
- pdb_set_unknown_5(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "unknown_6") && cur->ns == ns)
- pdb_set_unknown_6(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "homedir") && cur->ns == ns)
- pdb_set_homedir(u,
- xmlNodeListGetString(doc, cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "unknown_str") && cur->ns == ns)
- pdb_set_unknown_str(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "dir_drive") && cur->ns == ns)
- pdb_set_dir_drive(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "munged_dial") && cur->ns == ns)
- pdb_set_munged_dial(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "acct_desc") && cur->ns == ns)
- pdb_set_acct_desc(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "acct_ctrl") && cur->ns == ns)
- pdb_set_acct_ctrl(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "workstations") && cur->ns == ns)
- pdb_set_workstations(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if ((!strcmp(cur->name, "password")) && (cur->ns == ns)) {
- tmp = xmlGetProp(cur, "last_set");
- if (tmp)
- pdb_set_pass_last_set_time(u, atol(tmp), PDB_SET);
- tmp = xmlGetProp(cur, "must_change");
- if (tmp)
- pdb_set_pass_must_change_time(u, atol(tmp), PDB_SET);
- tmp = xmlGetProp(cur, "can_change");
- if (tmp)
- pdb_set_pass_can_change_time(u, atol(tmp), PDB_SET);
- parsePass(doc, ns, cur, u);
- }
-
- else
- DEBUG(0, ("Unknown element %s\n", cur->name));
- cur = cur->next;
- }
-
- return True;
-}
-
-typedef struct pdb_xml {
- char *location;
- char written;
- xmlDocPtr doc;
- xmlNodePtr users;
- xmlNodePtr pwent;
- xmlNsPtr ns;
-} pdb_xml;
-
-xmlNodePtr parseSambaXMLFile(struct pdb_xml *data)
-{
- xmlNodePtr cur;
-
- data->doc = xmlParseFile(data->location);
- if (data->doc == NULL)
- return NULL;
-
- cur = xmlDocGetRootElement(data->doc);
- if (!cur) {
- DEBUG(0, ("empty document\n"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
- data->ns = xmlSearchNsByHref(data->doc, cur, XML_URL);
- if (!data->ns) {
- DEBUG(0,
- ("document of the wrong type, samba user namespace not found\n"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
- if (strcmp(cur->name, "samba")) {
- DEBUG(0, ("document of the wrong type, root node != samba"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
-
- cur = cur->xmlChildrenNode;
- while (cur && xmlIsBlankNode(cur)) {
- cur = cur->next;
- }
- if (!cur)
- return NULL;
- if ((strcmp(cur->name, "users")) || (cur->ns != data->ns)) {
- DEBUG(0, ("document of the wrong type, was '%s', users expected",
- cur->name));
- DEBUG(0, ("xmlDocDump follows\n"));
- xmlDocDump(stderr, data->doc);
- DEBUG(0, ("xmlDocDump finished\n"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
- data->users = cur;
- cur = cur->xmlChildrenNode;
- return cur;
-}
-
-static NTSTATUS xmlsam_setsampwent(struct pdb_methods *methods, BOOL update)
-{
- pdb_xml *data;
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- data = (pdb_xml *) methods->private_data;
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- data->pwent = parseSambaXMLFile(data);
- if (!data->pwent)
- return NT_STATUS_UNSUCCESSFUL;
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************
- End enumeration of the passwd list.
- ****************************************************************/
-
-static void xmlsam_endsampwent(struct pdb_methods *methods)
-{
- pdb_xml *data;
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return;
- }
-
- data = (pdb_xml *) methods->private_data;
-
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return;
- }
-
- xmlFreeDoc(data->doc);
- data->doc = NULL;
- data->pwent = NULL;
-}
-
-/*****************************************************************
- Get one SAM_ACCOUNT from the list (next in line)
- *****************************************************************/
-
-static NTSTATUS xmlsam_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT * user)
-{
- pdb_xml *data;
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- data = (pdb_xml *) methods->private_data;
-
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- while (data->pwent) {
- if ((!strcmp(data->pwent->name, "user")) &&
- (data->pwent->ns == data->ns)) {
-
- parseUser(data->doc, data->ns, data->pwent, user);
- data->pwent = data->pwent->next;
- return NT_STATUS_OK;
- }
- data->pwent = data->pwent->next;
- }
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-/***************************************************************************
- Adds an existing SAM_ACCOUNT
- ****************************************************************************/
-
-static NTSTATUS xmlsam_add_sam_account(struct pdb_methods *methods, SAM_ACCOUNT * u)
-{
- pstring temp;
- fstring sid_str;
- xmlNodePtr cur, user, pass, root;
- pdb_xml *data;
-
- DEBUG(10, ("xmlsam_add_sam_account called!\n"));
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data = (pdb_xml *) methods->private_data;
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* Create a new document if we can't open the current one */
- if (!parseSambaXMLFile(data)) {
- DEBUG(0, ("Can't load current XML file, creating a new one\n"));
- data->doc = xmlNewDoc(XML_DEFAULT_VERSION);
- root = xmlNewDocNode(data->doc, NULL, "samba", NULL);
- cur = xmlDocSetRootElement(data->doc, root);
- data->ns = xmlNewNs(root, XML_URL, "samba");
- data->users = xmlNewChild(root, data->ns, "users", NULL);
- }
-
- user = xmlNewChild(data->users, data->ns, "user", NULL);
- xmlNewProp(user, "sid",
- sid_to_string(sid_str, pdb_get_user_sid(u)));
- if (pdb_get_init_flags(u, PDB_UID) != PDB_DEFAULT)
- xmlNewProp(user, "uid", iota(pdb_get_uid(u)));
-
- if (pdb_get_username(u) && strcmp(pdb_get_username(u), ""))
- xmlNewProp(user, "name", pdb_get_username(u));
-
- cur = xmlNewChild(user, data->ns, "group", NULL);
-
- xmlNewProp(cur, "sid",
- sid_to_string(sid_str, pdb_get_group_sid(u)));
- if (pdb_get_init_flags(u, PDB_GID) != PDB_DEFAULT)
- xmlNewProp(cur, "gid", iota(pdb_get_gid(u)));
-
- if (pdb_get_init_flags(u, PDB_LOGONTIME) != PDB_DEFAULT)
- xmlNewChild(user, data->ns, "login_time",
- iota(pdb_get_logon_time(u)));
-
- if (pdb_get_init_flags(u, PDB_LOGOFFTIME) != PDB_DEFAULT)
- xmlNewChild(user, data->ns, "logoff_time",
- iota(pdb_get_logoff_time(u)));
-
- if (pdb_get_init_flags(u, PDB_KICKOFFTIME) != PDB_DEFAULT)
- xmlNewChild(user, data->ns, "kickoff_time",
- iota(pdb_get_kickoff_time(u)));
-
- if (pdb_get_domain(u) && strcmp(pdb_get_domain(u), ""))
- xmlNewChild(user, data->ns, "domain", pdb_get_domain(u));
-
- if (pdb_get_nt_username(u) && strcmp(pdb_get_nt_username(u), ""))
- xmlNewChild(user, data->ns, "nt_username", pdb_get_nt_username(u));
-
- if (pdb_get_fullname(u) && strcmp(pdb_get_fullname(u), ""))
- xmlNewChild(user, data->ns, "fullname", pdb_get_fullname(u));
-
- if (pdb_get_homedir(u) && strcmp(pdb_get_homedir(u), ""))
- xmlNewChild(user, data->ns, "homedir", pdb_get_homedir(u));
-
- if (pdb_get_dir_drive(u) && strcmp(pdb_get_dir_drive(u), ""))
- xmlNewChild(user, data->ns, "dir_drive", pdb_get_dir_drive(u));
-
- if (pdb_get_logon_script(u) && strcmp(pdb_get_logon_script(u), ""))
- xmlNewChild(user, data->ns, "logon_script",
- pdb_get_logon_script(u));
-
- if (pdb_get_profile_path(u) && strcmp(pdb_get_profile_path(u), ""))
- xmlNewChild(user, data->ns, "profile_path",
- pdb_get_profile_path(u));
-
- if (pdb_get_acct_desc(u) && strcmp(pdb_get_acct_desc(u), ""))
- xmlNewChild(user, data->ns, "acct_desc", pdb_get_acct_desc(u));
-
- if (pdb_get_workstations(u) && strcmp(pdb_get_workstations(u), ""))
- xmlNewChild(user, data->ns, "workstations",
- pdb_get_workstations(u));
-
- if (pdb_get_unknown_str(u) && strcmp(pdb_get_unknown_str(u), ""))
- xmlNewChild(user, data->ns, "unknown_str", pdb_get_unknown_str(u));
-
- if (pdb_get_munged_dial(u) && strcmp(pdb_get_munged_dial(u), ""))
- xmlNewChild(user, data->ns, "munged_dial", pdb_get_munged_dial(u));
-
-
- /* Password stuff */
- pass = xmlNewChild(user, data->ns, "password", NULL);
- if (pdb_get_pass_last_set_time(u))
- xmlNewProp(pass, "last_set", iota(pdb_get_pass_last_set_time(u)));
- if (pdb_get_init_flags(u, PDB_CANCHANGETIME) != PDB_DEFAULT)
- xmlNewProp(pass, "can_change",
- iota(pdb_get_pass_can_change_time(u)));
-
- if (pdb_get_init_flags(u, PDB_MUSTCHANGETIME) != PDB_DEFAULT)
- xmlNewProp(pass, "must_change",
- iota(pdb_get_pass_must_change_time(u)));
-
-
- if (pdb_get_lanman_passwd(u)) {
- pdb_sethexpwd(temp, pdb_get_lanman_passwd(u),
- pdb_get_acct_ctrl(u));
- cur = xmlNewChild(pass, data->ns, "crypt", temp);
- xmlNewProp(cur, "type", "lanman");
- }
-
- if (pdb_get_nt_passwd(u)) {
- pdb_sethexpwd(temp, pdb_get_nt_passwd(u), pdb_get_acct_ctrl(u));
- cur = xmlNewChild(pass, data->ns, "crypt", temp);
- xmlNewProp(cur, "type", "nt");
- }
-
- xmlNewChild(user, data->ns, "acct_ctrl", iota(pdb_get_acct_ctrl(u)));
- xmlNewChild(user, data->ns, "unknown_3", iota(pdb_get_unknown_3(u)));
-
- if (pdb_get_logon_divs(u))
- xmlNewChild(user, data->ns, "logon_divs",
- iota(pdb_get_logon_divs(u)));
-
- if (pdb_get_hours_len(u))
- xmlNewChild(user, data->ns, "hours_len",
- iota(pdb_get_hours_len(u)));
-
- xmlNewChild(user, data->ns, "unknown_5", iota(pdb_get_unknown_5(u)));
- xmlNewChild(user, data->ns, "unknown_6", iota(pdb_get_unknown_6(u)));
- xmlSaveFile(data->location, data->doc);
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS xmlsam_init(PDB_CONTEXT * pdb_context, PDB_METHODS ** pdb_method,
- const char *location)
-{
- NTSTATUS nt_status;
- pdb_xml *data;
-
- xmlsam_debug_level = debug_add_class("xmlsam");
- if (xmlsam_debug_level == -1) {
- xmlsam_debug_level = DBGC_ALL;
- DEBUG(0, ("xmlsam: Couldn't register custom debugging class!\n"));
- }
-
- if (!pdb_context) {
- DEBUG(0, ("invalid pdb_methods specified\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK
- (nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "xmlsam";
-
- (*pdb_method)->setsampwent = xmlsam_setsampwent;
- (*pdb_method)->endsampwent = xmlsam_endsampwent;
- (*pdb_method)->getsampwent = xmlsam_getsampwent;
- (*pdb_method)->add_sam_account = xmlsam_add_sam_account;
- (*pdb_method)->getsampwnam = NULL;
- (*pdb_method)->getsampwsid = NULL;
- (*pdb_method)->update_sam_account = NULL;
- (*pdb_method)->delete_sam_account = NULL;
- (*pdb_method)->getgrsid = NULL;
- (*pdb_method)->getgrgid = NULL;
- (*pdb_method)->getgrnam = NULL;
- (*pdb_method)->add_group_mapping_entry = NULL;
- (*pdb_method)->update_group_mapping_entry = NULL;
- (*pdb_method)->delete_group_mapping_entry = NULL;
- (*pdb_method)->enum_group_mapping = NULL;
-
- data = talloc(pdb_context->mem_ctx, sizeof(pdb_xml));
- data->location =
- (location ? talloc_strdup(pdb_context->mem_ctx, location) : "-");
- data->pwent = NULL;
- data->written = 0;
- (*pdb_method)->private_data = data;
-
- LIBXML_TEST_VERSION xmlKeepBlanksDefault(0);
-
- return NT_STATUS_OK;
-}
-
-int init_module(void);
-
-int init_module()
-{
- if(smb_register_passdb("xml", xmlsam_init, PASSDB_INTERFACE_VERSION))
- return 0;
-
- return 1;
-}
diff --git a/source4/nmbd/asyncdns.c b/source4/nmbd/asyncdns.c
deleted file mode 100644
index c86ee69a09..0000000000
--- a/source4/nmbd/asyncdns.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- a async DNS handler
- Copyright (C) Andrew Tridgell 1997-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"
-
-/***************************************************************************
- Add a DNS result to the name cache.
-****************************************************************************/
-
-static struct name_record *add_dns_result(struct nmb_name *question, struct in_addr addr)
-{
- int name_type = question->name_type;
- char *qname = question->name;
-
-
- if (!addr.s_addr) {
- /* add the fail to WINS cache of names. give it 1 hour in the cache */
- DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname));
- (void)add_name_to_subnet( wins_server_subnet, qname, name_type,
- NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr );
- return( NULL );
- }
-
- /* add it to our WINS cache of names. give it 2 hours in the cache */
- DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
-
- return( add_name_to_subnet( wins_server_subnet, qname, name_type,
- NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr ) );
-}
-
-
-
-#ifndef SYNC_DNS
-
-static int fd_in = -1, fd_out = -1;
-static pid_t child_pid = -1;
-static int in_dns;
-
-/* this is the structure that is passed between the parent and child */
-struct query_record {
- struct nmb_name name;
- struct in_addr result;
-};
-
-/* a queue of pending requests waiting to be sent to the DNS child */
-static struct packet_struct *dns_queue;
-
-/* the packet currently being processed by the dns child */
-static struct packet_struct *dns_current;
-
-
-/***************************************************************************
- return the fd used to gather async dns replies. This is added to the select
- loop
- ****************************************************************************/
-int asyncdns_fd(void)
-{
- return fd_in;
-}
-
-/***************************************************************************
- handle DNS queries arriving from the parent
- ****************************************************************************/
-static void asyncdns_process(void)
-{
- struct query_record r;
- fstring qname;
-
- DEBUGLEVEL = -1;
-
- while (1) {
- if (read_data(fd_in, (char *)&r, sizeof(r)) != sizeof(r))
- break;
-
- fstrcpy(qname, r.name.name);
-
- r.result.s_addr = interpret_addr(qname);
-
- if (write_data(fd_out, (char *)&r, sizeof(r)) != sizeof(r))
- break;
- }
-
- _exit(0);
-}
-
-/**************************************************************************** **
- catch a sigterm (in the child process - the parent has a different handler
- see nmbd.c for details).
- We need a separate term handler here so we don't release any
- names that our parent is going to release, or overwrite a
- WINS db that our parent is going to write.
- **************************************************************************** */
-
-static void sig_term(int sig)
-{
- _exit(0);
-}
-
-/***************************************************************************
- Called by the parent process when it receives a SIGTERM - also kills the
- child so we don't get child async dns processes lying around, causing trouble.
- ****************************************************************************/
-
-void kill_async_dns_child(void)
-{
- if (child_pid > 0) {
- kill(child_pid, SIGTERM);
- child_pid = -1;
- }
-}
-
-/***************************************************************************
- create a child process to handle DNS lookups
- ****************************************************************************/
-void start_async_dns(void)
-{
- int fd1[2], fd2[2];
-
- CatchChild();
-
- if (pipe(fd1) || pipe(fd2)) {
- DEBUG(0,("can't create asyncdns pipes\n"));
- return;
- }
-
- child_pid = sys_fork();
-
- if (child_pid) {
- fd_in = fd1[0];
- fd_out = fd2[1];
- close(fd1[1]);
- close(fd2[0]);
- DEBUG(0,("started asyncdns process %d\n", (int)child_pid));
- return;
- }
-
- fd_in = fd2[0];
- fd_out = fd1[1];
-
- CatchSignal(SIGUSR2, SIG_IGN);
- CatchSignal(SIGUSR1, SIG_IGN);
- CatchSignal(SIGHUP, SIG_IGN);
- CatchSignal(SIGTERM, SIGNAL_CAST sig_term );
-
- asyncdns_process();
-}
-
-
-/***************************************************************************
-check if a particular name is already being queried
- ****************************************************************************/
-static BOOL query_current(struct query_record *r)
-{
- return dns_current &&
- nmb_name_equal(&r->name,
- &dns_current->packet.nmb.question.question_name);
-}
-
-
-/***************************************************************************
- write a query to the child process
- ****************************************************************************/
-static BOOL write_child(struct packet_struct *p)
-{
- struct query_record r;
-
- r.name = p->packet.nmb.question.question_name;
-
- return write_data(fd_out, (char *)&r, sizeof(r)) == sizeof(r);
-}
-
-/***************************************************************************
- check the DNS queue
- ****************************************************************************/
-void run_dns_queue(void)
-{
- struct query_record r;
- struct packet_struct *p, *p2;
- struct name_record *namerec;
- int size;
-
- if (fd_in == -1)
- return;
-
- /* Allow SIGTERM to kill us. */
- BlockSignals(False, SIGTERM);
-
- if (!process_exists(child_pid)) {
- close(fd_in);
- start_async_dns();
- }
-
- if ((size=read_data(fd_in, (char *)&r, sizeof(r))) != sizeof(r)) {
- if (size) {
- DEBUG(0,("Incomplete DNS answer from child!\n"));
- fd_in = -1;
- }
- BlockSignals(True, SIGTERM);
- return;
- }
-
- BlockSignals(True, SIGTERM);
-
- namerec = add_dns_result(&r.name, r.result);
-
- if (dns_current) {
- if (query_current(&r)) {
- DEBUG(3,("DNS calling send_wins_name_query_response\n"));
- in_dns = 1;
- if(namerec == NULL)
- send_wins_name_query_response(NAM_ERR, dns_current, NULL);
- else
- send_wins_name_query_response(0,dns_current,namerec);
- in_dns = 0;
- }
-
- dns_current->locked = False;
- free_packet(dns_current);
- dns_current = NULL;
- }
-
- /* loop over the whole dns queue looking for entries that
- match the result we just got */
- for (p = dns_queue; p;) {
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
-
- if (nmb_name_equal(question, &r.name)) {
- DEBUG(3,("DNS calling send_wins_name_query_response\n"));
- in_dns = 1;
- if(namerec == NULL)
- send_wins_name_query_response(NAM_ERR, p, NULL);
- else
- send_wins_name_query_response(0,p,namerec);
- in_dns = 0;
- p->locked = False;
-
- if (p->prev)
- p->prev->next = p->next;
- else
- dns_queue = p->next;
- if (p->next)
- p->next->prev = p->prev;
- p2 = p->next;
- free_packet(p);
- p = p2;
- } else {
- p = p->next;
- }
- }
-
- if (dns_queue) {
- dns_current = dns_queue;
- dns_queue = dns_queue->next;
- if (dns_queue) dns_queue->prev = NULL;
- dns_current->next = NULL;
-
- if (!write_child(dns_current)) {
- DEBUG(3,("failed to send DNS query to child!\n"));
- return;
- }
- }
-
-}
-
-/***************************************************************************
-queue a DNS query
- ****************************************************************************/
-BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
- struct name_record **n)
-{
- if (in_dns || fd_in == -1)
- return False;
-
- if (!dns_current) {
- if (!write_child(p)) {
- DEBUG(3,("failed to send DNS query to child!\n"));
- return False;
- }
- dns_current = p;
- p->locked = True;
- } else {
- p->locked = True;
- p->next = dns_queue;
- p->prev = NULL;
- if (p->next)
- p->next->prev = p;
- dns_queue = p;
- }
-
- DEBUG(3,("added DNS query for %s\n", nmb_namestr(question)));
- return True;
-}
-
-#else
-
-
-/***************************************************************************
- we use this when we can't do async DNS lookups
- ****************************************************************************/
-BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
- struct name_record **n)
-{
- char *qname = question->name;
- struct in_addr dns_ip;
-
- DEBUG(3,("DNS search for %s - ", nmb_namestr(question)));
-
- /* Unblock TERM signal so we can be killed in DNS lookup. */
- BlockSignals(False, SIGTERM);
-
- dns_ip.s_addr = interpret_addr(qname);
-
- /* Re-block TERM signal. */
- BlockSignals(True, SIGTERM);
-
- *n = add_dns_result(question, dns_ip);
- if(*n == NULL)
- send_wins_name_query_response(NAM_ERR, p, NULL);
- else
- send_wins_name_query_response(0, p, *n);
- return False;
-}
-
-/***************************************************************************
- With sync dns there is no child to kill on SIGTERM.
- ****************************************************************************/
-void kill_async_dns_child(void)
-{
- return;
-}
-#endif
diff --git a/source4/nmbd/nmbd.c b/source4/nmbd/nmbd.c
deleted file mode 100644
index 0fa3525666..0000000000
--- a/source4/nmbd/nmbd.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Jeremy Allison 1997-2002
- Copyright (C) Jelmer Vernooij 2002 (Conversion to popt)
-
- 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"
-
-int ClientNMB = -1;
-int ClientDGRAM = -1;
-int global_nmb_port = -1;
-
-extern BOOL global_in_nmbd;
-
-/* are we running as a daemon ? */
-static BOOL is_daemon = False;
-
-/* fork or run in foreground ? */
-static BOOL Fork = True;
-
-/* log to standard output ? */
-static BOOL log_stdout = False;
-
-/* have we found LanMan clients yet? */
-BOOL found_lm_clients = False;
-
-/* what server type are we currently */
-
-time_t StartupTime = 0;
-
-/**************************************************************************** **
- Handle a SIGTERM in band.
- **************************************************************************** */
-
-static void terminate(void)
-{
- DEBUG(0,("Got SIGTERM: going down...\n"));
-
- /* Write out wins.dat file if samba is a WINS server */
- wins_write_database(False);
-
- /* Remove all SELF registered names from WINS */
- release_wins_names();
-
- /* Announce all server entries as 0 time-to-live, 0 type. */
- announce_my_servers_removed();
-
- /* If there was an async dns child - kill it. */
- kill_async_dns_child();
-
- exit(0);
-}
-
-/**************************************************************************** **
- Handle a SHUTDOWN message from smbcontrol.
- **************************************************************************** */
-
-static void nmbd_terminate(int msg_type, pid_t src, void *buf, size_t len)
-{
- terminate();
-}
-
-/**************************************************************************** **
- Catch a SIGTERM signal.
- **************************************************************************** */
-
-static sig_atomic_t got_sig_term;
-
-static void sig_term(int sig)
-{
- got_sig_term = 1;
- sys_select_signal();
-}
-
-/**************************************************************************** **
- Catch a SIGHUP signal.
- **************************************************************************** */
-
-static sig_atomic_t reload_after_sighup;
-
-static void sig_hup(int sig)
-{
- reload_after_sighup = 1;
- sys_select_signal();
-}
-
-/*******************************************************************
- Print out all talloc memory info.
-********************************************************************/
-
-void return_all_talloc_info(int msg_type, pid_t src_pid, void *buf, size_t len)
-{
- TALLOC_CTX *ctx = talloc_init("info context");
- char *info = NULL;
-
- if (!ctx)
- return;
-
- info = talloc_describe_all(ctx);
- if (info)
- DEBUG(10,(info));
- message_send_pid(src_pid, MSG_TALLOC_USAGE, info, info ? strlen(info) + 1 : 0, True);
- talloc_destroy(ctx);
-}
-
-#if DUMP_CORE
-/**************************************************************************** **
- Prepare to dump a core file - carefully!
- **************************************************************************** */
-
-static BOOL dump_core(void)
-{
- char *p;
- pstring dname;
- pstrcpy( dname, lp_logfile() );
- if ((p=strrchr_m(dname,'/')))
- *p=0;
- pstrcat( dname, "/corefiles" );
- mkdir( dname, 0700 );
- sys_chown( dname, getuid(), getgid() );
- chmod( dname, 0700 );
- if ( chdir(dname) )
- return( False );
- umask( ~(0700) );
-
-#ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_CORE
- {
- struct rlimit rlp;
- getrlimit( RLIMIT_CORE, &rlp );
- rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
- setrlimit( RLIMIT_CORE, &rlp );
- getrlimit( RLIMIT_CORE, &rlp );
- DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
- }
-#endif
-#endif
-
-
- DEBUG(0,("Dumping core in %s\n",dname));
- abort();
- return( True );
-}
-#endif
-
-/**************************************************************************** **
- Possibly continue after a fault.
- **************************************************************************** */
-
-static void fault_continue(void)
-{
-#if DUMP_CORE
- dump_core();
-#endif
-}
-
-/**************************************************************************** **
- Expire old names from the namelist and server list.
- **************************************************************************** */
-
-static void expire_names_and_servers(time_t t)
-{
- static time_t lastrun = 0;
-
- if ( !lastrun )
- lastrun = t;
- if ( t < (lastrun + 5) )
- return;
- lastrun = t;
-
- /*
- * Expire any timed out names on all the broadcast
- * subnets and those registered with the WINS server.
- * (nmbd_namelistdb.c)
- */
-
- expire_names(t);
-
- /*
- * Go through all the broadcast subnets and for each
- * workgroup known on that subnet remove any expired
- * server names. If a workgroup has an empty serverlist
- * and has itself timed out then remove the workgroup.
- * (nmbd_workgroupdb.c)
- */
-
- expire_workgroups_and_servers(t);
-}
-
-/************************************************************************** **
- Reload the list of network interfaces.
- ************************************************************************** */
-
-static BOOL reload_interfaces(time_t t)
-{
- static time_t lastt;
- int n;
- struct subnet_record *subrec;
- extern BOOL rescan_listen_set;
- extern struct in_addr loopback_ip;
-
- if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False;
- lastt = t;
-
- if (!interfaces_changed()) return False;
-
- /* the list of probed interfaces has changed, we may need to add/remove
- some subnets */
- load_interfaces();
-
- /* find any interfaces that need adding */
- for (n=iface_count() - 1; n >= 0; n--) {
- struct interface *iface = get_interface(n);
-
- /*
- * We don't want to add a loopback interface, in case
- * someone has added 127.0.0.1 for smbd, nmbd needs to
- * ignore it here. JRA.
- */
-
- if (ip_equal(iface->ip, loopback_ip)) {
- DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
- continue;
- }
-
- for (subrec=subnetlist; subrec; subrec=subrec->next) {
- if (ip_equal(iface->ip, subrec->myip) &&
- ip_equal(iface->nmask, subrec->mask_ip)) break;
- }
-
- if (!subrec) {
- /* it wasn't found! add it */
- DEBUG(2,("Found new interface %s\n",
- inet_ntoa(iface->ip)));
- subrec = make_normal_subnet(iface);
- if (subrec) register_my_workgroup_one_subnet(subrec);
- }
- }
-
- /* find any interfaces that need deleting */
- for (subrec=subnetlist; subrec; subrec=subrec->next) {
- for (n=iface_count() - 1; n >= 0; n--) {
- struct interface *iface = get_interface(n);
- if (ip_equal(iface->ip, subrec->myip) &&
- ip_equal(iface->nmask, subrec->mask_ip)) break;
- }
- if (n == -1) {
- /* oops, an interface has disapeared. This is
- tricky, we don't dare actually free the
- interface as it could be being used, so
- instead we just wear the memory leak and
- remove it from the list of interfaces without
- freeing it */
- DEBUG(2,("Deleting dead interface %s\n",
- inet_ntoa(subrec->myip)));
- close_subnet(subrec);
- }
- }
-
- rescan_listen_set = True;
-
- /* We need to shutdown if there are no subnets... */
- if (FIRST_SUBNET == NULL) {
- DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n"));
- return True;
- }
- return False;
-}
-
-/**************************************************************************** **
- Reload the services file.
- **************************************************************************** */
-
-static BOOL reload_nmbd_services(BOOL test)
-{
- BOOL ret;
-
- set_remote_machine_name("nmbd");
-
- if ( lp_loaded() ) {
- pstring fname;
- pstrcpy( fname,lp_configfile());
- if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
- pstrcpy(dyn_CONFIGFILE,fname);
- test = False;
- }
- }
-
- if ( test && !lp_file_list_changed() )
- return(True);
-
- ret = lp_load( dyn_CONFIGFILE, True , False, False);
-
- /* perhaps the config filename is now set */
- if ( !test ) {
- DEBUG( 3, ( "services not loaded\n" ) );
- reload_nmbd_services( True );
- }
-
- return(ret);
-}
-
-/**************************************************************************** **
- The main select loop.
- **************************************************************************** */
-
-static void process(void)
-{
- BOOL run_election;
-
- while( True ) {
- time_t t = time(NULL);
-
- /* Check for internal messages */
-
- message_dispatch();
-
- /*
- * Check all broadcast subnets to see if
- * we need to run an election on any of them.
- * (nmbd_elections.c)
- */
-
- run_election = check_elections();
-
- /*
- * Read incoming UDP packets.
- * (nmbd_packets.c)
- */
-
- if(listen_for_packets(run_election))
- return;
-
- /*
- * Handle termination inband.
- */
-
- if (got_sig_term) {
- got_sig_term = 0;
- terminate();
- }
-
- /*
- * Process all incoming packets
- * read above. This calls the success and
- * failure functions registered when response
- * packets arrrive, and also deals with request
- * packets from other sources.
- * (nmbd_packets.c)
- */
-
- run_packet_queue();
-
- /*
- * Run any elections - initiate becoming
- * a local master browser if we have won.
- * (nmbd_elections.c)
- */
-
- run_elections(t);
-
- /*
- * Send out any broadcast announcements
- * of our server names. This also announces
- * the workgroup name if we are a local
- * master browser.
- * (nmbd_sendannounce.c)
- */
-
- announce_my_server_names(t);
-
- /*
- * Send out any LanMan broadcast announcements
- * of our server names.
- * (nmbd_sendannounce.c)
- */
-
- announce_my_lm_server_names(t);
-
- /*
- * If we are a local master browser, periodically
- * announce ourselves to the domain master browser.
- * This also deals with syncronising the domain master
- * browser server lists with ourselves as a local
- * master browser.
- * (nmbd_sendannounce.c)
- */
-
- announce_myself_to_domain_master_browser(t);
-
- /*
- * Fullfill any remote announce requests.
- * (nmbd_sendannounce.c)
- */
-
- announce_remote(t);
-
- /*
- * Fullfill any remote browse sync announce requests.
- * (nmbd_sendannounce.c)
- */
-
- browse_sync_remote(t);
-
- /*
- * Scan the broadcast subnets, and WINS client
- * namelists and refresh any that need refreshing.
- * (nmbd_mynames.c)
- */
-
- refresh_my_names(t);
-
- /*
- * Scan the subnet namelists and server lists and
- * expire thos that have timed out.
- * (nmbd.c)
- */
-
- expire_names_and_servers(t);
-
- /*
- * Write out a snapshot of our current browse list into
- * the browse.dat file. This is used by smbd to service
- * incoming NetServerEnum calls - used to synchronise
- * browse lists over subnets.
- * (nmbd_serverlistdb.c)
- */
-
- write_browse_list(t, False);
-
- /*
- * If we are a domain master browser, we have a list of
- * local master browsers we should synchronise browse
- * lists with (these are added by an incoming local
- * master browser announcement packet). Expire any of
- * these that are no longer current, and pull the server
- * lists from each of these known local master browsers.
- * (nmbd_browsesync.c)
- */
-
- dmb_expire_and_sync_browser_lists(t);
-
- /*
- * Check that there is a local master browser for our
- * workgroup for all our broadcast subnets. If one
- * is not found, start an election (which we ourselves
- * may or may not participate in, depending on the
- * setting of the 'local master' parameter.
- * (nmbd_elections.c)
- */
-
- check_master_browser_exists(t);
-
- /*
- * If we are configured as a logon server, attempt to
- * register the special NetBIOS names to become such
- * (WORKGROUP<1c> name) on all broadcast subnets and
- * with the WINS server (if used). If we are configured
- * to become a domain master browser, attempt to register
- * the special NetBIOS name (WORKGROUP<1b> name) to
- * become such.
- * (nmbd_become_dmb.c)
- */
-
- add_domain_names(t);
-
- /*
- * If we are a WINS server, do any timer dependent
- * processing required.
- * (nmbd_winsserver.c)
- */
-
- initiate_wins_processing(t);
-
- /*
- * If we are a domain master browser, attempt to contact the
- * WINS server to get a list of all known WORKGROUPS/DOMAINS.
- * This will only work to a Samba WINS server.
- * (nmbd_browsesync.c)
- */
-
- if (lp_enhanced_browsing())
- collect_all_workgroup_names_from_wins_server(t);
-
- /*
- * Go through the response record queue and time out or re-transmit
- * and expired entries.
- * (nmbd_packets.c)
- */
-
- retransmit_or_expire_response_records(t);
-
- /*
- * check to see if any remote browse sync child processes have completed
- */
-
- sync_check_completion();
-
- /*
- * regularly sync with any other DMBs we know about
- */
-
- if (lp_enhanced_browsing())
- sync_all_dmbs(t);
-
- /*
- * clear the unexpected packet queue
- */
-
- clear_unexpected(t);
-
- /*
- * Reload the services file if we got a sighup.
- */
-
- if(reload_after_sighup) {
- DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
- write_browse_list( 0, True );
- dump_all_namelists();
- reload_nmbd_services( True );
- reopen_logs();
- if(reload_interfaces(0))
- return;
- reload_after_sighup = 0;
- }
-
- /* check for new network interfaces */
-
- if(reload_interfaces(t))
- return;
-
- /* free up temp memory */
- lp_talloc_free();
- }
-}
-
-/**************************************************************************** **
- Open the socket communication.
- **************************************************************************** */
-
-static BOOL open_sockets(BOOL isdaemon, int port)
-{
- /*
- * The sockets opened here will be used to receive broadcast
- * packets *only*. Interface specific sockets are opened in
- * make_subnet() in namedbsubnet.c. Thus we bind to the
- * address "0.0.0.0". The parameter 'socket address' is
- * now deprecated.
- */
-
- if ( isdaemon )
- ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0,True);
- else
- ClientNMB = 0;
-
- ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0,True);
-
- if ( ClientNMB == -1 )
- return( False );
-
- /* we are never interested in SIGPIPE */
- BlockSignals(True,SIGPIPE);
-
- set_socket_options( ClientNMB, "SO_BROADCAST" );
- set_socket_options( ClientDGRAM, "SO_BROADCAST" );
-
- DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
- return( True );
-}
-
-/**************************************************************************** **
- main program
- **************************************************************************** */
- int main(int argc, const char *argv[])
-{
- static BOOL opt_interactive = False;
- poptContext pc;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" },
- {"interactive", 'i', POPT_ARG_VAL, &opt_interactive, True, "Run interactive (not a daemon)" },
- {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
- {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
- {"hosts", 'H', POPT_ARG_STRING, dyn_LMHOSTSFILE, 'H', "Load a netbios hosts file"},
- {"port", 'p', POPT_ARG_INT, &global_nmb_port, NMB_PORT, "Listen on the specified port" },
- {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug },
- {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_configfile },
- {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_socket_options },
- {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version },
- {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_netbios_name },
- {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_log_base },
- { NULL }
- };
- int opt;
- pstring logfile;
-
- global_nmb_port = NMB_PORT;
- global_in_nmbd = True;
-
- StartupTime = time(NULL);
-
- sys_srandom(time(NULL) ^ sys_getpid());
-
- slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
- lp_set_logfile(logfile);
-
- fault_setup((void (*)(void *))fault_continue );
-
- /* POSIX demands that signals are inherited. If the invoking process has
- * these signals masked, we will have problems, as we won't recieve them. */
- BlockSignals(False, SIGHUP);
- BlockSignals(False, SIGUSR1);
- BlockSignals(False, SIGTERM);
-
- CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
- CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
-
-#if defined(SIGFPE)
- /* we are never interested in SIGFPE */
- BlockSignals(True,SIGFPE);
-#endif
-
- /* We no longer use USR2... */
-#if defined(SIGUSR2)
- BlockSignals(True, SIGUSR2);
-#endif
- pc = poptGetContext("nmbd", argc, argv, long_options, 0);
-
- while((opt = poptGetNextOpt(pc)) != -1)
- { }
-
- poptFreeContext(pc);
-
- if ( opt_interactive ) {
- Fork = False;
- log_stdout = True;
- }
-
- if ( log_stdout && Fork ) {
- DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
- exit(1);
- }
-
- setup_logging( argv[0], log_stdout?DEBUG_STDOUT : DEBUG_FILE );
-
- reopen_logs();
-
- DEBUG( 0, ( "Netbios nameserver version %s started.\n", VERSION ) );
- DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2002\n" ) );
-
- if ( !reload_nmbd_services(False) )
- return(-1);
-
- if(!init_names())
- return -1;
-
- reload_nmbd_services( True );
-
- if (strequal(lp_workgroup(),"*"))
- {
- DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
- exit(1);
- }
-
- set_samba_nb_type();
-
- if (!is_daemon && !is_a_socket(0))
- {
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
- is_daemon = True;
- }
-
- if (is_daemon && !opt_interactive)
- {
- DEBUG( 2, ( "Becoming a daemon.\n" ) );
- become_daemon(Fork);
- }
-
-#if HAVE_SETPGID
- /*
- * If we're interactive we want to set our own process group for
- * signal management.
- */
- if (opt_interactive)
- setpgid( (pid_t)0, (pid_t)0 );
-#endif
-
-#ifndef SYNC_DNS
- /* Setup the async dns. We do it here so it doesn't have all the other
- stuff initialised and thus chewing memory and sockets */
- if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
- start_async_dns();
- }
-#endif
-
- if (!directory_exist(lp_lockdir(), NULL)) {
- mkdir(lp_lockdir(), 0755);
- }
-
- pidfile_create("nmbd");
- message_init();
- message_register(MSG_FORCE_ELECTION, nmbd_message_election);
- message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
- message_register(MSG_SHUTDOWN, nmbd_terminate);
- message_register(MSG_REQ_TALLOC_USAGE, return_all_talloc_info);
-
- DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
-
- if ( !open_sockets( is_daemon, global_nmb_port ) ) {
- kill_async_dns_child();
- return 1;
- }
-
- /* Determine all the IP addresses we have. */
- load_interfaces();
-
- /* Create an nmbd subnet record for each of the above. */
- if( False == create_subnets() )
- {
- DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
- kill_async_dns_child();
- exit(1);
- }
-
- /* Load in any static local names. */
- load_lmhosts_file(dyn_LMHOSTSFILE);
- DEBUG(3,("Loaded hosts file %s\n", dyn_LMHOSTSFILE));
-
- /* If we are acting as a WINS server, initialise data structures. */
- if( !initialise_wins() )
- {
- DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
- kill_async_dns_child();
- exit(1);
- }
-
- /*
- * Register nmbd primary workgroup and nmbd names on all
- * the broadcast subnets, and on the WINS server (if specified).
- * Also initiate the startup of our primary workgroup (start
- * elections if we are setup as being able to be a local
- * master browser.
- */
-
- if( False == register_my_workgroup_and_names() )
- {
- DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
- kill_async_dns_child();
- exit(1);
- }
-
- /* We can only take signals in the select. */
- BlockSignals( True, SIGTERM );
-
- process();
-
- if (dbf)
- x_fclose(dbf);
- kill_async_dns_child();
- return(0);
-}
diff --git a/source4/nmbd/nmbd_become_dmb.c b/source4/nmbd/nmbd_become_dmb.c
deleted file mode 100644
index d8122777fe..0000000000
--- a/source4/nmbd/nmbd_become_dmb.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-extern struct in_addr allones_ip;
-
-extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
-
-static void become_domain_master_browser_bcast(const char *);
-
-/****************************************************************************
- Fail to become a Domain Master Browser on a subnet.
- ****************************************************************************/
-
-static void become_domain_master_fail(struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *fail_name)
-{
- struct work_record *work = find_workgroup_on_subnet(subrec, fail_name->name);
- struct server_record *servrec;
-
- if(!work)
- {
- DEBUG(0,("become_domain_master_fail: Error - cannot find \
-workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
- return;
- }
-
- /* Set the state back to DOMAIN_NONE. */
- work->dom_state = DOMAIN_NONE;
-
- if((servrec = find_server_in_workgroup( work, lp_netbios_name())) == NULL)
- {
- DEBUG(0,("become_domain_master_fail: Error - cannot find server %s \
-in workgroup %s on subnet %s\n",
- lp_netbios_name(), work->work_group, subrec->subnet_name));
- return;
- }
-
- /* Update our server status. */
- servrec->serv.type &= ~SV_TYPE_DOMAIN_MASTER;
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- DEBUG(0,("become_domain_master_fail: Failed to become a domain master browser for \
-workgroup %s on subnet %s. Couldn't register name %s.\n",
- work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
-}
-
-/****************************************************************************
- Become a Domain Master Browser on a subnet.
- ****************************************************************************/
-
-static void become_domain_master_stage2(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *registered_name,
- uint16 nb_flags,
- int ttl, struct in_addr registered_ip)
-{
- struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
- struct server_record *servrec;
-
- if(!work)
- {
- DEBUG(0,("become_domain_master_stage2: Error - cannot find \
-workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, lp_netbios_name())) == NULL)
- {
- DEBUG(0,("become_domain_master_stage2: Error - cannot find server %s \
-in workgroup %s on subnet %s\n",
- lp_netbios_name(), registered_name->name, subrec->subnet_name));
- work->dom_state = DOMAIN_NONE;
- return;
- }
-
- /* Set the state in the workgroup structure. */
- work->dom_state = DOMAIN_MST; /* Become domain master. */
-
- /* Update our server status. */
- servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER);
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "*****\n\nSamba server %s ", lp_netbios_name() );
- dbgtext( "is now a domain master browser for " );
- dbgtext( "workgroup %s ", work->work_group );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
-
- if( subrec == unicast_subnet )
- {
- struct nmb_name nmbname;
- struct in_addr my_first_ip;
-
- /* Put our name and first IP address into the
- workgroup struct as domain master browser. This
- will stop us syncing with ourself if we are also
- a local master browser. */
-
- make_nmb_name(&nmbname, lp_netbios_name(), 0x20);
-
- work->dmb_name = nmbname;
- /* Pick the first interface ip address as the domain master browser ip. */
- my_first_ip = *iface_n_ip(0);
-
- putip((char *)&work->dmb_addr, &my_first_ip);
-
- /* We successfully registered by unicast with the
- WINS server. We now expect to become the domain
- master on the local subnets. If this fails, it's
- probably a 1.9.16p2 to 1.9.16p11 server's fault.
-
- This is a configuration issue that should be addressed
- by the network administrator - you shouldn't have
- several machines configured as a domain master browser
- for the same WINS scope (except if they are 1.9.17 or
- greater, and you know what you're doing.
-
- see docs/DOMAIN.txt.
-
- */
- become_domain_master_browser_bcast(work->work_group);
- }
- else
- {
- /*
- * Now we are a domain master on a broadcast subnet, we need to add
- * the WORKGROUP<1b> name to the unicast subnet so that we can answer
- * unicast requests sent to this name. This bug wasn't found for a while
- * as it is strange to have a DMB without using WINS. JRA.
- */
- insert_permanent_name_into_unicast(subrec, registered_name, nb_flags);
- }
-}
-
-/****************************************************************************
- Start the name registration process when becoming a Domain Master Browser
- on a subnet.
- ****************************************************************************/
-
-static void become_domain_master_stage1(struct subnet_record *subrec, char *wg_name)
-{
- struct work_record *work;
-
- DEBUG(2,("become_domain_master_stage1: Becoming domain master browser for \
-workgroup %s on subnet %s\n", wg_name, subrec->subnet_name));
-
- /* First, find the workgroup on the subnet. */
- if((work = find_workgroup_on_subnet( subrec, wg_name )) == NULL)
- {
- DEBUG(0,("become_domain_master_stage1: Error - unable to find workgroup %s on subnet %s.\n",
- wg_name, subrec->subnet_name));
- return;
- }
-
- DEBUG(3,("become_domain_master_stage1: go to first stage: register <1b> name\n"));
- work->dom_state = DOMAIN_WAIT;
-
- /* WORKGROUP<1b> is the domain master browser name. */
- register_name(subrec, work->work_group,0x1b,samba_nb_type,
- become_domain_master_stage2,
- become_domain_master_fail, NULL);
-}
-
-/****************************************************************************
- Function called when a query for a WORKGROUP<1b> name succeeds.
- This is normally a fail condition as it means there is already
- a domain master browser for a workgroup and we were trying to
- become one.
-****************************************************************************/
-
-static void become_domain_master_query_success(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname, struct in_addr ip,
- struct res_rec *rrec)
-{
- /* If the given ip is not ours, then we can't become a domain
- controler as the name is already registered.
- */
-
- /* BUG note. Samba 1.9.16p11 servers seem to return the broadcast
- address or zero ip for this query. Pretend this is ok. */
-
- if(ismyip(ip) || ip_equal(allones_ip, ip) || is_zero_ip(ip))
- {
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "become_domain_master_query_success():\n" );
- dbgtext( "Our address (%s) ", inet_ntoa(ip) );
- dbgtext( "returned in query for name %s ", nmb_namestr(nmbname) );
- dbgtext( "(domain master browser name) " );
- dbgtext( "on subnet %s.\n", subrec->subnet_name );
- dbgtext( "Continuing with domain master code.\n" );
- }
-
- become_domain_master_stage1(subrec, nmbname->name);
- }
- else
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "become_domain_master_query_success:\n" );
- dbgtext( "There is already a domain master browser at " );
- dbgtext( "IP %s for workgroup %s ", inet_ntoa(ip), nmbname->name );
- dbgtext( "registered on subnet %s.\n", subrec->subnet_name );
- }
- }
-}
-
-/****************************************************************************
- Function called when a query for a WORKGROUP<1b> name fails.
- This is normally a success condition as it then allows us to register
- our own Domain Master Browser name.
- ****************************************************************************/
-
-static void become_domain_master_query_fail(struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *question_name, int fail_code)
-{
- /* If the query was unicast, and the error is not NAM_ERR (name didn't exist),
- then this is a failure. Otherwise, not finding the name is what we want. */
- if((subrec == unicast_subnet) && (fail_code != NAM_ERR))
- {
- DEBUG(0,("become_domain_master_query_fail: Error %d returned when \
-querying WINS server for name %s.\n",
- fail_code, nmb_namestr(question_name)));
- return;
- }
-
- /* Otherwise - not having the name allows us to register it. */
- become_domain_master_stage1(subrec, question_name->name);
-}
-
-/****************************************************************************
- Attempt to become a domain master browser on all broadcast subnets.
- ****************************************************************************/
-
-static void become_domain_master_browser_bcast(const char *workgroup_name)
-{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name);
-
- if (work && (work->dom_state == DOMAIN_NONE))
- {
- struct nmb_name nmbname;
- make_nmb_name(&nmbname,workgroup_name,0x1b);
-
- /*
- * Check for our name on the given broadcast subnet first, only initiate
- * further processing if we cannot find it.
- */
-
- if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "become_domain_master_browser_bcast:\n" );
- dbgtext( "Attempting to become domain master browser on " );
- dbgtext( "workgroup %s on subnet %s\n",
- workgroup_name, subrec->subnet_name );
- }
-
- /* Send out a query to establish whether there's a
- domain controller on the local subnet. If not,
- we can become a domain controller.
- */
-
- DEBUG(0,("become_domain_master_browser_bcast: querying subnet %s \
-for domain master browser on workgroup %s\n", subrec->subnet_name, workgroup_name));
-
- query_name(subrec, nmbname.name, nmbname.name_type,
- become_domain_master_query_success,
- become_domain_master_query_fail,
- NULL);
- }
- }
- }
-}
-
-/****************************************************************************
- Attempt to become a domain master browser by registering with WINS.
- ****************************************************************************/
-
-static void become_domain_master_browser_wins(const char *workgroup_name)
-{
- struct work_record *work;
-
- work = find_workgroup_on_subnet(unicast_subnet, workgroup_name);
-
- if (work && (work->dom_state == DOMAIN_NONE))
- {
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname,workgroup_name,0x1b);
-
- /*
- * Check for our name on the unicast subnet first, only initiate
- * further processing if we cannot find it.
- */
-
- if (find_name_on_subnet(unicast_subnet, &nmbname, FIND_SELF_NAME) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "become_domain_master_browser_wins:\n" );
- dbgtext( "Attempting to become domain master browser " );
- dbgtext( "on workgroup %s, subnet %s.\n",
- workgroup_name, unicast_subnet->subnet_name );
- }
-
- /* Send out a query to establish whether there's a
- domain master broswer registered with WINS. If not,
- we can become a domain master browser.
- */
-
- DEBUG(0,("become_domain_master_browser_wins: querying WINS server from IP %s \
-for domain master browser name %s on workgroup %s\n",
- inet_ntoa(unicast_subnet->myip), nmb_namestr(&nmbname), workgroup_name));
-
- query_name(unicast_subnet, nmbname.name, nmbname.name_type,
- become_domain_master_query_success,
- become_domain_master_query_fail,
- NULL);
- }
- }
-}
-
-/****************************************************************************
- Add the domain logon server and domain master browser names
- if we are set up to do so.
- **************************************************************************/
-
-void add_domain_names(time_t t)
-{
- static time_t lastrun = 0;
-
- if ((lastrun != 0) && (t < lastrun + (CHECK_TIME_ADD_DOM_NAMES * 60)))
- return;
-
- lastrun = t;
-
- /* Do the "internet group" - <1c> names. */
- if (lp_domain_logons())
- add_logon_names();
-
- /* Do the domain master names. */
- if(lp_server_role() == ROLE_DOMAIN_PDC)
- {
- if(we_are_a_wins_client())
- {
- /* We register the WORKGROUP<1b> name with the WINS
- server first, and call add_domain_master_bcast()
- only if this is successful.
-
- This results in domain logon services being gracefully provided,
- as opposed to the aggressive nature of 1.9.16p2 to 1.9.16p11.
- 1.9.16p2 to 1.9.16p11 - due to a bug in namelogon.c,
- cannot provide domain master / domain logon services.
- */
- become_domain_master_browser_wins(lp_workgroup());
- }
- else
- become_domain_master_browser_bcast(lp_workgroup());
- }
-}
diff --git a/source4/nmbd/nmbd_become_lmb.c b/source4/nmbd/nmbd_become_lmb.c
deleted file mode 100644
index 8b87ca7444..0000000000
--- a/source4/nmbd/nmbd_become_lmb.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
-
-/*******************************************************************
- Utility function to add a name to the unicast subnet, or add in
- our IP address if it already exists.
-******************************************************************/
-
-void insert_permanent_name_into_unicast( struct subnet_record *subrec,
- struct nmb_name *nmbname, uint16 nb_type )
-{
- struct name_record *namerec;
-
- if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
- {
- /* The name needs to be created on the unicast subnet. */
- (void)add_name_to_subnet( unicast_subnet, nmbname->name,
- nmbname->name_type, nb_type,
- PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
- }
- else
- {
- /* The name already exists on the unicast subnet. Add our local
- IP for the given broadcast subnet to the name. */
- add_ip_to_name_record( namerec, subrec->myip);
- }
-}
-
-/*******************************************************************
- Utility function to remove a name from the unicast subnet.
-******************************************************************/
-
-static void remove_permanent_name_from_unicast( struct subnet_record *subrec,
- struct nmb_name *nmbname )
-{
- struct name_record *namerec;
-
- if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) != NULL)
- {
- /* Remove this broadcast subnet IP address from the name. */
- remove_ip_from_name_record( namerec, subrec->myip);
- if(namerec->data.num_ips == 0)
- remove_name_from_namelist( unicast_subnet, namerec);
- }
-}
-
-/*******************************************************************
- Utility function always called to set our workgroup and server
- state back to potential browser, or none.
-******************************************************************/
-
-static void reset_workgroup_state( struct subnet_record *subrec, char *workgroup_name,
- BOOL force_new_election )
-{
- struct work_record *work;
- struct server_record *servrec;
- struct nmb_name nmbname;
-
- if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL)
- {
- DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
-subnet %s.\n", workgroup_name, subrec->subnet_name ));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, lp_netbios_name())) == NULL)
- {
- DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
-in workgroup %s on subnet %s\n",
- lp_netbios_name(), work->work_group, subrec->subnet_name));
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- return;
- }
-
- /* Update our server status - remove any master flag and replace
- it with the potential browser flag. */
- servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
- servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- /* Reset our election flags. */
- work->ElectionCriterion &= ~0x4;
-
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
-
- /* Forget who the local master browser was for
- this workgroup. */
-
- set_workgroup_local_master_browser_name( work, "");
-
- /*
- * Ensure the IP address of this subnet is not registered as one
- * of the IP addresses of the WORKGROUP<1d> name on the unicast
- * subnet. This undoes what we did below when we became a local
- * master browser.
- */
-
- make_nmb_name(&nmbname, work->work_group, 0x1d);
-
- remove_permanent_name_from_unicast( subrec, &nmbname);
-
- if(force_new_election)
- work->needelection = True;
-}
-
-/*******************************************************************
- Unbecome the local master browser name release success function.
-******************************************************************/
-
-static void unbecome_local_master_success(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *released_name,
- struct in_addr released_ip)
-{
- BOOL force_new_election = False;
-
- memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
-
- DEBUG(3,("unbecome_local_master_success: released name %s.\n",
- nmb_namestr(released_name)));
-
- /* Now reset the workgroup and server state. */
- reset_workgroup_state( subrec, released_name->name, force_new_election );
-
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "*****\n\n" );
- dbgtext( "Samba name server %s ", lp_netbios_name() );
- dbgtext( "has stopped being a local master browser " );
- dbgtext( "for workgroup %s ", released_name->name );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
-
-}
-
-/*******************************************************************
- Unbecome the local master browser name release fail function.
-******************************************************************/
-
-static void unbecome_local_master_fail(struct subnet_record *subrec, struct response_record *rrec,
- struct nmb_name *fail_name)
-{
- struct name_record *namerec;
- struct userdata_struct *userdata = rrec->userdata;
- BOOL force_new_election = False;
-
- memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
-
- DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
-Removing from namelist anyway.\n", nmb_namestr(fail_name)));
-
- /* Do it anyway. */
- namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
- if(namerec)
- remove_name_from_namelist(subrec, namerec);
-
- /* Now reset the workgroup and server state. */
- reset_workgroup_state( subrec, fail_name->name, force_new_election );
-
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "*****\n\n" );
- dbgtext( "Samba name server %s ", lp_netbios_name() );
- dbgtext( "has stopped being a local master browser " );
- dbgtext( "for workgroup %s ", fail_name->name );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
-}
-
-/*******************************************************************
- Utility function to remove the WORKGROUP<1d> name.
-******************************************************************/
-
-static void release_1d_name( struct subnet_record *subrec, char *workgroup_name,
- BOOL force_new_election)
-{
- struct nmb_name nmbname;
- struct name_record *namerec;
-
- make_nmb_name(&nmbname, workgroup_name, 0x1d);
- if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
- {
- struct userdata_struct *userdata;
- int size = sizeof(struct userdata_struct) + sizeof(BOOL);
-
- if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
- {
- DEBUG(0,("release_1d_name: malloc fail.\n"));
- return;
- }
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = sizeof(BOOL);
- memcpy((char *)userdata->data, &force_new_election, sizeof(BOOL));
-
- release_name(subrec, namerec,
- unbecome_local_master_success,
- unbecome_local_master_fail,
- userdata);
-
- zero_free(userdata, size);
- }
-}
-
-/*******************************************************************
- Unbecome the local master browser MSBROWSE name release success function.
-******************************************************************/
-
-static void release_msbrowse_name_success(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *released_name,
- struct in_addr released_ip)
-{
- DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
- nmb_namestr(released_name), subrec->subnet_name ));
-
- /* Remove the permanent MSBROWSE name added into the unicast subnet. */
- remove_permanent_name_from_unicast( subrec, released_name);
-}
-
-/*******************************************************************
- Unbecome the local master browser MSBROWSE name release fail function.
-******************************************************************/
-
-static void release_msbrowse_name_fail( struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *fail_name)
-{
- struct name_record *namerec;
-
- DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
- nmb_namestr(fail_name), subrec->subnet_name ));
-
- /* Release the name anyway. */
- namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
- if(namerec)
- remove_name_from_namelist(subrec, namerec);
-
- /* Remove the permanent MSBROWSE name added into the unicast subnet. */
- remove_permanent_name_from_unicast( subrec, fail_name);
-}
-
-/*******************************************************************
- Unbecome the local master browser. If force_new_election is true, restart
- the election process after we've unbecome the local master.
-******************************************************************/
-
-void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work,
- BOOL force_new_election)
-{
- struct name_record *namerec;
- struct nmb_name nmbname;
-
- /* Sanity check. */
-
- DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
-on subnet %s\n",work->work_group, subrec->subnet_name));
-
- if(find_server_in_workgroup( work, lp_netbios_name()) == NULL)
- {
- DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
-in workgroup %s on subnet %s\n",
- lp_netbios_name(), work->work_group, subrec->subnet_name));
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- return;
- }
-
- /* Set the state to unbecoming. */
- work->mst_state = MST_UNBECOMING_MASTER;
-
- /*
- * Release the WORKGROUP<1d> name asap to allow another machine to
- * claim it.
- */
-
- release_1d_name( subrec, work->work_group, force_new_election);
-
- /* Deregister any browser names we may have. */
- make_nmb_name(&nmbname, MSBROWSE, 0x1);
- if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
- {
- release_name(subrec, namerec,
- release_msbrowse_name_success,
- release_msbrowse_name_fail,
- NULL);
- }
-
- /*
- * Ensure we have sent and processed these release packets
- * before returning - we don't want to process any election
- * packets before dealing with the 1d release.
- */
-
- retransmit_or_expire_response_records(time(NULL));
-}
-
-/****************************************************************************
- Success in registering the WORKGROUP<1d> name.
- We are now *really* a local master browser.
- ****************************************************************************/
-
-static void become_local_master_stage2(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *registered_name,
- uint16 nb_flags,
- int ttl, struct in_addr registered_ip)
-{
- int i = 0;
- struct server_record *sl;
- struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
- struct server_record *servrec;
-
- if(!work)
- {
- DEBUG(0,("become_local_master_stage2: Error - cannot find \
-workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, lp_netbios_name())) == NULL)
- {
- DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
-in workgroup %s on subnet %s\n",
- lp_netbios_name(), registered_name->name, subrec->subnet_name));
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- return;
- }
-
- DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
-on subnet %s\n", work->work_group, subrec->subnet_name));
-
- work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
-
- /* update our server status */
- servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
- servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- /* Add this name to the workgroup as local master browser. */
- set_workgroup_local_master_browser_name( work, lp_netbios_name());
-
- /* Count the number of servers we have on our list. If it's
- less than 10 (just a heuristic) request the servers
- to announce themselves.
- */
- for( sl = work->serverlist; sl != NULL; sl = sl->next)
- i++;
-
- if (i < 10)
- {
- /* Ask all servers on our local net to announce to us. */
- broadcast_announce_request(subrec, work);
- }
-
- /*
- * Now we are a local master on a broadcast subnet, we need to add
- * the WORKGROUP<1d> name to the unicast subnet so that we can answer
- * unicast requests sent to this name. We can create this name directly on
- * the unicast subnet as a WINS server always returns true when registering
- * this name, and discards the registration. We use the number of IP
- * addresses registered to this name as a reference count, as we
- * remove this broadcast subnet IP address from it when we stop becoming a local
- * master browser for this broadcast subnet.
- */
-
- insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
-
- /* Reset the announce master browser timer so that we try and tell a domain
- master browser as soon as possible that we are a local master browser. */
- reset_announce_timer();
-
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "*****\n\n" );
- dbgtext( "Samba name server %s ", lp_netbios_name() );
- dbgtext( "is now a local master browser " );
- dbgtext( "for workgroup %s ", work->work_group );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
-
-}
-
-/****************************************************************************
- Failed to register the WORKGROUP<1d> name.
- ****************************************************************************/
-static void become_local_master_fail2(struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *fail_name)
-{
- struct work_record *work = find_workgroup_on_subnet( subrec, fail_name->name);
-
- DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
-Failed to become a local master browser.\n", nmb_namestr(fail_name), subrec->subnet_name));
-
- if(!work)
- {
- DEBUG(0,("become_local_master_fail2: Error - cannot find \
-workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
- return;
- }
-
- /* Roll back all the way by calling unbecome_local_master_browser(). */
- unbecome_local_master_browser(subrec, work, False);
-}
-
-/****************************************************************************
- Success in registering the MSBROWSE name.
- ****************************************************************************/
-
-static void become_local_master_stage1(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *registered_name,
- uint16 nb_flags,
- int ttl, struct in_addr registered_ip)
-{
- char *work_name = userdata->data;
- struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
-
- if(!work)
- {
- DEBUG(0,("become_local_master_stage1: Error - cannot find \
-workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
- return;
- }
-
- DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
- work->work_group));
-
- work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
-
- /*
- * We registered the MSBROWSE name on a broadcast subnet, now need to add
- * the MSBROWSE name to the unicast subnet so that we can answer
- * unicast requests sent to this name. We create this name directly on
- * the unicast subnet.
- */
-
- insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
-
- /* Attempt to register the WORKGROUP<1d> name. */
- register_name(subrec, work->work_group,0x1d,samba_nb_type,
- become_local_master_stage2,
- become_local_master_fail2,
- NULL);
-}
-
-/****************************************************************************
- Failed to register the MSBROWSE name.
- ****************************************************************************/
-
-static void become_local_master_fail1(struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *fail_name)
-{
- char *work_name = rrec->userdata->data;
- struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
-
- if(!work)
- {
- DEBUG(0,("become_local_master_fail1: Error - cannot find \
-workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
- return;
- }
-
- if(find_server_in_workgroup(work, lp_netbios_name()) == NULL)
- {
- DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
-in workgroup %s on subnet %s\n",
- lp_netbios_name(), work->work_group, subrec->subnet_name));
- return;
- }
-
- reset_workgroup_state( subrec, work->work_group, False );
-
- DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
-workgroup %s on subnet %s. Couldn't register name %s.\n",
- work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
-}
-
-/******************************************************************
- Become the local master browser on a subnet.
- This gets called if we win an election on this subnet.
-
- Stage 1: mst_state was MST_POTENTIAL - go to MST_BACK register ^1^2__MSBROWSE__^2^1.
- Stage 2: mst_state was MST_BACKUP - go to MST_MSB and register WORKGROUP<1d>.
- Stage 3: mst_state was MST_MSB - go to MST_BROWSER.
-******************************************************************/
-
-void become_local_master_browser(struct subnet_record *subrec, struct work_record *work)
-{
- struct userdata_struct *userdata;
- int size = sizeof(struct userdata_struct) + sizeof(fstring) + 1;
-
- /* Sanity check. */
- if (!lp_local_master())
- {
- DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
- return;
- }
-
- if(!AM_POTENTIAL_MASTER_BROWSER(work))
- {
- DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
- work->mst_state ));
- return;
- }
-
- if(find_server_in_workgroup( work, lp_netbios_name()) == NULL)
- {
- DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
-in workgroup %s on subnet %s\n",
- lp_netbios_name(), work->work_group, subrec->subnet_name));
- return;
- }
-
- DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
-%s on subnet %s\n", work->work_group, subrec->subnet_name));
-
- DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
- work->mst_state = MST_BACKUP; /* an election win was successful */
-
- work->ElectionCriterion |= 0x5;
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- /* Setup the userdata_struct. */
- if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
- {
- DEBUG(0,("become_local_master_browser: malloc fail.\n"));
- return;
- }
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = strlen(work->work_group)+1;
- fstrcpy(userdata->data, work->work_group);
-
- /* Register the special browser group name. */
- register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
- become_local_master_stage1,
- become_local_master_fail1,
- userdata);
-
- zero_free(userdata, size);
-}
-
-/***************************************************************
- Utility function to set the local master browser name. Does
- some sanity checking as old versions of Samba seem to sometimes
- say that the master browser name for a workgroup is the same
- as the workgroup name.
-****************************************************************/
-
-void set_workgroup_local_master_browser_name( struct work_record *work, const char *newname)
-{
- DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
-for workgroup %s.\n", newname, work->work_group ));
-
-#if 0
- /*
- * Apparently some sites use the workgroup name as the local
- * master browser name. Arrrrggghhhhh ! (JRA).
- */
- if(strequal( work->work_group, newname))
- {
- DEBUG(5, ("set_workgroup_local_master_browser_name: Refusing to set \
-local_master_browser_name for workgroup %s to workgroup name.\n",
- work->work_group ));
- return;
- }
-#endif
-
- StrnCpy(work->local_master_browser_name, newname,
- sizeof(work->local_master_browser_name)-1);
-}
diff --git a/source4/nmbd/nmbd_browserdb.c b/source4/nmbd/nmbd_browserdb.c
deleted file mode 100644
index a4ef98e265..0000000000
--- a/source4/nmbd/nmbd_browserdb.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
- Copyright (C) Christopher R. Hertel 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.
-
-*/
-/* -------------------------------------------------------------------------- **
- * Modified July 1998 by CRH.
- * I converted this module to use the canned doubly-linked lists. I also
- * added comments above the functions where possible.
- */
-
-#include "includes.h"
-
-/* -------------------------------------------------------------------------- **
- * Variables...
- *
- * lmb_browserlist - This is our local master browser list.
- */
-
-ubi_dlNewList( lmb_browserlist );
-
-
-/* -------------------------------------------------------------------------- **
- * Functions...
- */
-
-/* ************************************************************************** **
- * Remove and free a browser list entry.
- *
- * Input: browc - A pointer to the entry to be removed from the list and
- * freed.
- * Output: none.
- *
- * ************************************************************************** **
- */
-static void remove_lmb_browser_entry( struct browse_cache_record *browc )
- {
- safe_free( ubi_dlRemThis( lmb_browserlist, browc ) );
- } /* remove_lmb_browser_entry */
-
-/* ************************************************************************** **
- * Update a browser death time.
- *
- * Input: browc - Pointer to the entry to be updated.
- * Output: none.
- *
- * ************************************************************************** **
- */
-void update_browser_death_time( struct browse_cache_record *browc )
- {
- /* Allow the new lmb to miss an announce period before we remove it. */
- browc->death_time = time(NULL) + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
- } /* update_browser_death_time */
-
-/* ************************************************************************** **
- * Create a browser entry and add it to the local master browser list.
- *
- * Input: work_name
- * browser_name
- * ip
- *
- * Output: Pointer to the new entry, or NULL if malloc() failed.
- *
- * ************************************************************************** **
- */
-struct browse_cache_record *create_browser_in_lmb_cache( char *work_name,
- char *browser_name,
- struct in_addr ip )
- {
- struct browse_cache_record *browc;
- time_t now = time( NULL );
-
- browc = (struct browse_cache_record *)malloc( sizeof( *browc ) );
-
- if( NULL == browc )
- {
- DEBUG( 0, ("create_browser_in_lmb_cache: malloc fail !\n") );
- return( NULL );
- }
-
- memset( (char *)browc, '\0', sizeof( *browc ) );
-
- /* For a new lmb entry we want to sync with it after one minute. This
- will allow it time to send out a local announce and build its
- browse list.
- */
- browc->sync_time = now + 60;
-
- /* Allow the new lmb to miss an announce period before we remove it. */
- browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
-
- StrnCpy( browc->lmb_name, browser_name, sizeof(browc->lmb_name)-1 );
- StrnCpy( browc->work_group, work_name, sizeof(browc->work_group)-1 );
- strupper( browc->lmb_name );
- strupper( browc->work_group );
-
- browc->ip = ip;
-
- (void)ubi_dlAddTail( lmb_browserlist, browc );
-
- if( DEBUGLVL( 3 ) )
- {
- Debug1( "nmbd_browserdb:create_browser_in_lmb_cache()\n" );
- Debug1( " Added lmb cache entry for workgroup %s ", browc->work_group );
- Debug1( "name %s IP %s ", browc->lmb_name, inet_ntoa(ip) );
- Debug1( "ttl %d\n", (int)browc->death_time );
- }
-
- return( browc );
- } /* create_browser_in_lmb_cache */
-
-/* ************************************************************************** **
- * Find a browser entry in the local master browser list.
- *
- * Input: browser_name - The name for which to search.
- *
- * Output: A pointer to the matching entry, or NULL if no match was found.
- *
- * ************************************************************************** **
- */
-struct browse_cache_record *find_browser_in_lmb_cache( char *browser_name )
- {
- struct browse_cache_record *browc;
-
- for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
- browc;
- browc = (struct browse_cache_record *)ubi_dlNext( browc ) )
- if( strequal( browser_name, browc->lmb_name ) )
- break;
-
- return( browc );
- } /* find_browser_in_lmb_cache */
-
-/* ************************************************************************** **
- * Expire timed out browsers in the browserlist.
- *
- * Input: t - Expiration time. Entries with death times less than this
- * value will be removed from the list.
- * Output: none.
- *
- * ************************************************************************** **
- */
-void expire_lmb_browsers( time_t t )
- {
- struct browse_cache_record *browc;
- struct browse_cache_record *nextbrowc;
-
- for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
- browc;
- browc = nextbrowc )
- {
- nextbrowc = (struct browse_cache_record *)ubi_dlNext( browc );
-
- if( browc->death_time < t )
- {
- if( DEBUGLVL( 3 ) )
- {
- Debug1( "nmbd_browserdb:expire_lmb_browsers()\n" );
- Debug1( " Removing timed out lmb entry %s\n", browc->lmb_name );
- }
- remove_lmb_browser_entry( browc );
- }
- }
- } /* expire_lmb_browsers */
diff --git a/source4/nmbd/nmbd_browsesync.c b/source4/nmbd/nmbd_browsesync.c
deleted file mode 100644
index ff022a7bb1..0000000000
--- a/source4/nmbd/nmbd_browsesync.c
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-/* This is our local master browser list database. */
-extern ubi_dlList lmb_browserlist[];
-
-/****************************************************************************
-As a domain master browser, do a sync with a local master browser.
-**************************************************************************/
-static void sync_with_lmb(struct browse_cache_record *browc)
-{
- struct work_record *work;
-
- if( !(work = find_workgroup_on_subnet(unicast_subnet, browc->work_group)) )
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "sync_with_lmb:\n" );
- dbgtext( "Failed to get a workgroup for a local master browser " );
- dbgtext( "cache entry workgroup " );
- dbgtext( "%s, server %s\n", browc->work_group, browc->lmb_name );
- }
- return;
- }
-
- /* We should only be doing this if we are a domain master browser for
- the given workgroup. Ensure this is so. */
-
- if(!AM_DOMAIN_MASTER_BROWSER(work))
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "sync_with_lmb:\n" );
- dbgtext( "We are trying to sync with a local master browser " );
- dbgtext( "%s for workgroup %s\n", browc->lmb_name, browc->work_group );
- dbgtext( "and we are not a domain master browser on this workgroup.\n" );
- dbgtext( "Error!\n" );
- }
- return;
- }
-
- if( DEBUGLVL( 2 ) )
- {
- dbgtext( "sync_with_lmb:\n" );
- dbgtext( "Initiating sync with local master browser " );
- dbgtext( "%s<0x20> at IP %s ", browc->lmb_name, inet_ntoa(browc->ip) );
- dbgtext( "for workgroup %s\n", browc->work_group );
- }
-
- sync_browse_lists(work, browc->lmb_name, 0x20, browc->ip, True, True);
-
- browc->sync_time += (CHECK_TIME_DMB_TO_LMB_SYNC * 60);
-}
-
-/****************************************************************************
-Sync or expire any local master browsers.
-**************************************************************************/
-void dmb_expire_and_sync_browser_lists(time_t t)
-{
- static time_t last_run = 0;
- struct browse_cache_record *browc;
-
- /* Only do this every 20 seconds. */
- if (t - last_run < 20)
- return;
-
- last_run = t;
-
- expire_lmb_browsers(t);
-
- for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
- browc;
- browc = (struct browse_cache_record *)ubi_dlNext( browc ) )
- {
- if (browc->sync_time < t)
- sync_with_lmb(browc);
- }
-}
-
-/****************************************************************************
-As a local master browser, send an announce packet to the domain master browser.
-**************************************************************************/
-
-static void announce_local_master_browser_to_domain_master_browser( struct work_record *work)
-{
- pstring outbuf;
- char *p;
-
- if(ismyip(work->dmb_addr))
- {
- if( DEBUGLVL( 2 ) )
- {
- dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
- dbgtext( "We are both a domain and a local master browser for " );
- dbgtext( "workgroup %s. ", work->work_group );
- dbgtext( "Do not announce to ourselves.\n" );
- }
- return;
- }
-
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_MasterAnnouncement);
- p++;
-
- StrnCpy(p,lp_netbios_name(),15);
- strupper(p);
- p = skip_string(p,1);
-
- if( DEBUGLVL( 4 ) )
- {
- dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
- dbgtext( "Sending local master announce to " );
- dbgtext( "%s for workgroup %s.\n", nmb_namestr(&work->dmb_name),
- work->work_group );
- }
-
- send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- lp_netbios_name(), 0x0, work->dmb_name.name, 0x0,
- work->dmb_addr, FIRST_SUBNET->myip, DGRAM_PORT);
-
-}
-
-/****************************************************************************
-As a local master browser, do a sync with a domain master browser.
-**************************************************************************/
-
-static void sync_with_dmb(struct work_record *work)
-{
- if( DEBUGLVL( 2 ) )
- {
- dbgtext( "sync_with_dmb:\n" );
- dbgtext( "Initiating sync with domain master browser " );
- dbgtext( "%s ", nmb_namestr(&work->dmb_name) );
- dbgtext( "at IP %s ", inet_ntoa(work->dmb_addr) );
- dbgtext( "for workgroup %s\n", work->work_group );
- }
-
- sync_browse_lists(work, work->dmb_name.name, work->dmb_name.name_type,
- work->dmb_addr, False, True);
-}
-
-/****************************************************************************
- Function called when a node status query to a domain master browser IP succeeds.
-****************************************************************************/
-
-static void domain_master_node_status_success(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct res_rec *answers,
- struct in_addr from_ip)
-{
- struct work_record *work = find_workgroup_on_subnet( subrec, userdata->data);
-
- if( work == NULL )
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "domain_master_node_status_success:\n" );
- dbgtext( "Unable to find workgroup " );
- dbgtext( "%s on subnet %s.\n", userdata->data, subrec->subnet_name );
- }
- return;
- }
-
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "domain_master_node_status_success:\n" );
- dbgtext( "Success in node status for workgroup " );
- dbgtext( "%s from ip %s\n", work->work_group, inet_ntoa(from_ip) );
- }
-
- /* Go through the list of names found at answers->rdata and look for
- the first SERVER<0x20> name. */
-
- if(answers->rdata != NULL)
- {
- char *p = answers->rdata;
- int numnames = CVAL(p, 0);
-
- p += 1;
-
- while (numnames--)
- {
- char qname[17];
- uint16 nb_flags;
- int name_type;
-
- StrnCpy(qname,p,15);
- name_type = CVAL(p,15);
- nb_flags = get_nb_flags(&p[16]);
- trim_string(qname,NULL," ");
-
- p += 18;
-
- if(!(nb_flags & NB_GROUP) && (name_type == 0x20))
- {
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, qname, name_type);
-
- /* Copy the dmb name and IP address
- into the workgroup struct. */
-
- work->dmb_name = nmbname;
- putip((char *)&work->dmb_addr, &from_ip);
-
- /* Do the local master browser announcement to the domain
- master browser name and IP. */
- announce_local_master_browser_to_domain_master_browser( work );
-
- /* Now synchronise lists with the domain master browser. */
- sync_with_dmb(work);
- break;
- }
- }
- }
- else
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "domain_master_node_status_success:\n" );
- dbgtext( "Failed to find a SERVER<0x20> name in reply from IP " );
- dbgtext( "%s.\n", inet_ntoa(from_ip) );
- }
-}
-
-/****************************************************************************
- Function called when a node status query to a domain master browser IP fails.
-****************************************************************************/
-
-static void domain_master_node_status_fail(struct subnet_record *subrec,
- struct response_record *rrec)
-{
- struct userdata_struct *userdata = rrec->userdata;
-
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "domain_master_node_status_fail:\n" );
- dbgtext( "Doing a node status request to the domain master browser\n" );
- dbgtext( "for workgroup %s ", userdata->data );
- dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
- dbgtext( "Cannot sync browser lists.\n" );
- }
-}
-
-/****************************************************************************
- Function called when a query for a WORKGROUP<1b> name succeeds.
-****************************************************************************/
-
-static void find_domain_master_name_query_success(struct subnet_record *subrec,
- struct userdata_struct *userdata_in,
- struct nmb_name *q_name, struct in_addr answer_ip, struct res_rec *rrec)
-{
- /*
- * Unfortunately, finding the IP address of the Domain Master Browser,
- * as we have here, is not enough. We need to now do a sync to the
- * SERVERNAME<0x20> NetBIOS name, as only recent NT servers will
- * respond to the SMBSERVER name. To get this name from IP
- * address we do a Node status request, and look for the first
- * NAME<0x20> in the response, and take that as the server name.
- * We also keep a cache of the Domain Master Browser name for this
- * workgroup in the Workgroup struct, so that if the same IP addess
- * is returned every time, we don't need to do the node status
- * request.
- */
-
- struct work_record *work;
- struct nmb_name nmbname;
- struct userdata_struct *userdata;
- int size = sizeof(struct userdata_struct) + sizeof(fstring)+1;
-
- if( !(work = find_workgroup_on_subnet(subrec, q_name->name)) )
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "find_domain_master_name_query_success:\n" );
- dbgtext( "Failed to find workgroup %s\n", q_name->name );
- }
- return;
- }
-
- /* First check if we already have a dmb for this workgroup. */
-
- if(!is_zero_ip(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip))
- {
- /* Do the local master browser announcement to the domain
- master browser name and IP. */
- announce_local_master_browser_to_domain_master_browser( work );
-
- /* Now synchronise lists with the domain master browser. */
- sync_with_dmb(work);
- return;
- }
- else
- zero_ip(&work->dmb_addr);
-
- /* Now initiate the node status request. */
- make_nmb_name(&nmbname,"*",0x0);
-
- /* Put the workgroup name into the userdata so we know
- what workgroup we're talking to when the reply comes
- back. */
-
- /* Setup the userdata_struct - this is copied so we can use
- a stack variable for this. */
- if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
- {
- DEBUG(0, ("find_domain_master_name_query_success: malloc fail.\n"));
- return;
- }
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = strlen(work->work_group)+1;
- fstrcpy(userdata->data, work->work_group);
-
- node_status( subrec, &nmbname, answer_ip,
- domain_master_node_status_success,
- domain_master_node_status_fail,
- userdata);
-
- zero_free(userdata, size);
-}
-
-/****************************************************************************
- Function called when a query for a WORKGROUP<1b> name fails.
- ****************************************************************************/
-static void find_domain_master_name_query_fail(struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *question_name, int fail_code)
-{
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "find_domain_master_name_query_fail:\n" );
- dbgtext( "Unable to find the Domain Master Browser name " );
- dbgtext( "%s for the workgroup %s.\n",
- nmb_namestr(question_name), question_name->name );
- dbgtext( "Unable to sync browse lists in this workgroup.\n" );
- }
-}
-
-/****************************************************************************
-As a local master browser for a workgroup find the domain master browser
-name, announce ourselves as local master browser to it and then pull the
-full domain browse lists from it onto the given subnet.
-**************************************************************************/
-
-void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec,
- struct work_record *work)
-{
- struct nmb_name nmbname;
-
- /* Only do this if we are using a WINS server. */
- if(we_are_a_wins_client() == False)
- {
- if( DEBUGLVL( 10 ) )
- {
- dbgtext( "announce_and_sync_with_domain_master_browser:\n" );
- dbgtext( "Ignoring, as we are not a WINS client.\n" );
- }
- return;
- }
-
- make_nmb_name(&nmbname,work->work_group,0x1b);
-
- /* First, query for the WORKGROUP<1b> name from the WINS server. */
- query_name(unicast_subnet, nmbname.name, nmbname.name_type,
- find_domain_master_name_query_success,
- find_domain_master_name_query_fail,
- NULL);
-
-}
-
-/****************************************************************************
- Function called when a node status query to a domain master browser IP succeeds.
- This function is only called on query to a Samba 1.9.18 or above WINS server.
-
- Note that adding the workgroup name is enough for this workgroup to be
- browsable by clients, as clients query the WINS server or broadcast
- nets for the WORKGROUP<1b> name when they want to browse a workgroup
- they are not in. We do not need to do a sync with this Domain Master
- Browser in order for our browse clients to see machines in this workgroup.
- JRA.
-****************************************************************************/
-
-static void get_domain_master_name_node_status_success(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct res_rec *answers,
- struct in_addr from_ip)
-{
- struct work_record *work;
- fstring server_name;
-
- server_name[0] = 0;
-
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "get_domain_master_name_node_status_success:\n" );
- dbgtext( "Success in node status from ip %s\n", inet_ntoa(from_ip) );
- }
-
- /*
- * Go through the list of names found at answers->rdata and look for
- * the first WORKGROUP<0x1b> name.
- */
-
- if(answers->rdata != NULL)
- {
- char *p = answers->rdata;
- int numnames = CVAL(p, 0);
-
- p += 1;
-
- while (numnames--)
- {
- char qname[17];
- uint16 nb_flags;
- int name_type;
-
- StrnCpy(qname,p,15);
- name_type = CVAL(p,15);
- nb_flags = get_nb_flags(&p[16]);
- trim_string(qname,NULL," ");
-
- p += 18;
-
- if(!(nb_flags & NB_GROUP) && (name_type == 0x00) &&
- server_name[0] == 0) {
- /* this is almost certainly the server netbios name */
- fstrcpy(server_name, qname);
- continue;
- }
-
- if(!(nb_flags & NB_GROUP) && (name_type == 0x1b))
- {
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "get_domain_master_name_node_status_success:\n" );
- dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) );
- dbgtext( "is a domain master browser for workgroup " );
- dbgtext( "%s. Adding this name.\n", qname );
- }
-
- /*
- * If we don't already know about this workgroup, add it
- * to the workgroup list on the unicast_subnet.
- */
- if((work = find_workgroup_on_subnet( subrec, qname)) == NULL)
- {
- struct nmb_name nmbname;
- /*
- * Add it - with an hour in the cache.
- */
- if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60)))
- return;
-
- /* remember who the master is */
- fstrcpy(work->local_master_browser_name, server_name);
- make_nmb_name(&nmbname, server_name, 0x20);
- work->dmb_name = nmbname;
- work->dmb_addr = from_ip;
- }
- break;
- }
- }
- }
- else
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "get_domain_master_name_node_status_success:\n" );
- dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " );
- dbgtext( "%s.\n", inet_ntoa(from_ip) );
- }
-}
-
-/****************************************************************************
- Function called when a node status query to a domain master browser IP fails.
-****************************************************************************/
-
-static void get_domain_master_name_node_status_fail(struct subnet_record *subrec,
- struct response_record *rrec)
-{
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "get_domain_master_name_node_status_fail:\n" );
- dbgtext( "Doing a node status request to the domain master browser " );
- dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
- dbgtext( "Cannot get workgroup name.\n" );
- }
-}
-
-/****************************************************************************
- Function called when a query for *<1b> name succeeds.
-****************************************************************************/
-
-static void find_all_domain_master_names_query_success(struct subnet_record *subrec,
- struct userdata_struct *userdata_in,
- struct nmb_name *q_name, struct in_addr answer_ip, struct res_rec *rrec)
-{
- /*
- * We now have a list of all the domain master browsers for all workgroups
- * that have registered with the WINS server. Now do a node status request
- * to each one and look for the first 1b name in the reply. This will be
- * the workgroup name that we will add to the unicast subnet as a 'non-local'
- * workgroup.
- */
-
- struct nmb_name nmbname;
- struct in_addr send_ip;
- int i;
-
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "find_all_domain_master_names_query_succes:\n" );
- dbgtext( "Got answer from WINS server of %d ", (rrec->rdlength / 6) );
- dbgtext( "IP addresses for Domain Master Browsers.\n" );
- }
-
- for(i = 0; i < rrec->rdlength / 6; i++)
- {
- /* Initiate the node status requests. */
- make_nmb_name(&nmbname, "*", 0);
-
- putip((char *)&send_ip, (char *)&rrec->rdata[(i*6) + 2]);
-
- /*
- * Don't send node status requests to ourself.
- */
-
- if(ismyip( send_ip ))
- {
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "find_all_domain_master_names_query_succes:\n" );
- dbgtext( "Not sending node status to our own IP " );
- dbgtext( "%s.\n", inet_ntoa(send_ip) );
- }
- continue;
- }
-
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "find_all_domain_master_names_query_success:\n" );
- dbgtext( "Sending node status request to IP %s.\n", inet_ntoa(send_ip) );
- }
-
- node_status( subrec, &nmbname, send_ip,
- get_domain_master_name_node_status_success,
- get_domain_master_name_node_status_fail,
- NULL);
- }
-}
-
-/****************************************************************************
- Function called when a query for *<1b> name fails.
- ****************************************************************************/
-static void find_all_domain_master_names_query_fail(struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *question_name, int fail_code)
-{
- if( DEBUGLVL( 10 ) )
- {
- dbgtext( "find_domain_master_name_query_fail:\n" );
- dbgtext( "WINS server did not reply to a query for name " );
- dbgtext( "%s.\nThis means it ", nmb_namestr(question_name) );
- dbgtext( "is probably not a Samba 1.9.18 or above WINS server.\n" );
- }
-}
-
-/****************************************************************************
- If we are a domain master browser on the unicast subnet, do a query to the
- WINS server for the *<1b> name. This will only work to a Samba WINS server,
- so ignore it if we fail. If we succeed, contact each of the IP addresses in
- turn and do a node status request to them. If this succeeds then look for a
- <1b> name in the reply - this is the workgroup name. Add this to the unicast
- subnet. This is expensive, so we only do this every 15 minutes.
-**************************************************************************/
-void collect_all_workgroup_names_from_wins_server(time_t t)
-{
- static time_t lastrun = 0;
- struct work_record *work;
- struct nmb_name nmbname;
-
- /* Only do this if we are using a WINS server. */
- if(we_are_a_wins_client() == False)
- return;
-
- /* Check to see if we are a domain master browser on the unicast subnet. */
- if((work = find_workgroup_on_subnet( unicast_subnet, lp_workgroup())) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "collect_all_workgroup_names_from_wins_server:\n" );
- dbgtext( "Cannot find my workgroup %s ", lp_workgroup() );
- dbgtext( "on subnet %s.\n", unicast_subnet->subnet_name );
- }
- return;
- }
-
- if(!AM_DOMAIN_MASTER_BROWSER(work))
- return;
-
- if ((lastrun != 0) && (t < lastrun + (15 * 60)))
- return;
-
- lastrun = t;
-
- make_nmb_name(&nmbname,"*",0x1b);
-
- /* First, query for the *<1b> name from the WINS server. */
- query_name(unicast_subnet, nmbname.name, nmbname.name_type,
- find_all_domain_master_names_query_success,
- find_all_domain_master_names_query_fail,
- NULL);
-}
-
-
-/****************************************************************************
- If we are a domain master browser on the unicast subnet, do a regular sync
- with all other DMBs that we know of on that subnet.
-
-To prevent exponential network traffic with large numbers of workgroups
-we use a randomised system where sync probability is inversely proportional
-to the number of known workgroups
-**************************************************************************/
-void sync_all_dmbs(time_t t)
-{
- static time_t lastrun = 0;
- struct work_record *work;
- int count=0;
-
- /* Only do this if we are using a WINS server. */
- if(we_are_a_wins_client() == False)
- return;
-
- /* Check to see if we are a domain master browser on the
- unicast subnet. */
- work = find_workgroup_on_subnet(unicast_subnet, lp_workgroup());
- if (!work) return;
-
- if (!AM_DOMAIN_MASTER_BROWSER(work))
- return;
-
- if ((lastrun != 0) && (t < lastrun + (5 * 60)))
- return;
-
- /* count how many syncs we might need to do */
- for (work=unicast_subnet->workgrouplist; work; work = work->next) {
- if (strcmp(lp_workgroup(), work->work_group)) {
- count++;
- }
- }
-
- /* sync with a probability of 1/count */
- for (work=unicast_subnet->workgrouplist; work; work = work->next) {
- if (strcmp(lp_workgroup(), work->work_group)) {
- if (((unsigned)sys_random()) % count != 0) continue;
-
- lastrun = t;
-
- if (!work->dmb_name.name[0]) {
- /* we don't know the DMB - assume it is
- the same as the unicast local master */
- make_nmb_name(&work->dmb_name,
- work->local_master_browser_name,
- 0x20);
- }
-
- DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n",
- work->dmb_name.name,
- inet_ntoa(work->dmb_addr)));
- sync_browse_lists(work,
- work->dmb_name.name,
- work->dmb_name.name_type,
- work->dmb_addr, False, False);
- }
- }
-}
diff --git a/source4/nmbd/nmbd_elections.c b/source4/nmbd/nmbd_elections.c
deleted file mode 100644
index 759379cc84..0000000000
--- a/source4/nmbd/nmbd_elections.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-/* Election parameters. */
-extern time_t StartupTime;
-
-/****************************************************************************
- Send an election datagram packet.
-**************************************************************************/
-static void send_election_dgram(struct subnet_record *subrec, const char *workgroup_name,
- uint32 criterion, int timeup,const char *server_name)
-{
- pstring outbuf;
- char *p;
-
- DEBUG(2,("send_election_dgram: Sending election packet for workgroup %s on subnet %s\n",
- workgroup_name, subrec->subnet_name ));
-
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_Election); /* Election opcode. */
- p++;
-
- SCVAL(p,0,((criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION));
- SIVAL(p,1,criterion);
- SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */
- p += 13;
- pstrcpy(p,server_name);
- strupper(p);
- p = skip_string(p,1);
-
- send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
- lp_netbios_name(), 0,
- workgroup_name, 0x1e,
- subrec->bcast_ip, subrec->myip, DGRAM_PORT);
-}
-
-/*******************************************************************
- We found a current master browser on one of our broadcast interfaces.
-******************************************************************/
-
-static void check_for_master_browser_success(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *answer_name,
- struct in_addr answer_ip, struct res_rec *rrec)
-{
- DEBUG(3,("check_for_master_browser_success: Local master browser for workgroup %s exists at \
-IP %s (just checking).\n", answer_name->name, inet_ntoa(answer_ip) ));
-}
-
-/*******************************************************************
- We failed to find a current master browser on one of our broadcast interfaces.
-******************************************************************/
-
-static void check_for_master_browser_fail( struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *question_name,
- int fail_code)
-{
- char *workgroup_name = question_name->name;
- struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name);
-
- if(work == NULL)
- {
- DEBUG(0,("check_for_master_browser_fail: Unable to find workgroup %s on subnet %s.=\n",
- workgroup_name, subrec->subnet_name ));
- return;
- }
-
- if (strequal(work->work_group, lp_workgroup()))
- {
-
- if (lp_local_master())
- {
- /* We have discovered that there is no local master
- browser, and we are configured to initiate
- an election that we will participate in.
- */
- DEBUG(2,("check_for_master_browser_fail: Forcing election on workgroup %s subnet %s\n",
- work->work_group, subrec->subnet_name ));
-
- /* Setting this means we will participate when the
- election is run in run_elections(). */
- work->needelection = True;
- }
- else
- {
- /* We need to force an election, because we are configured
- not to become the local master, but we still need one,
- having detected that one doesn't exist.
- */
- send_election_dgram(subrec, work->work_group, 0, 0, "");
- }
- }
-}
-
-/*******************************************************************
- Ensure there is a local master browser for a workgroup on our
- broadcast interfaces.
-******************************************************************/
-
-void check_master_browser_exists(time_t t)
-{
- static time_t lastrun=0;
- struct subnet_record *subrec;
- const char *workgroup_name = lp_workgroup();
-
- if (!lastrun)
- lastrun = t;
-
- if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60)))
- return;
-
- lastrun = t;
-
- dump_workgroups(False);
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
-
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- if (strequal(work->work_group, workgroup_name) && !AM_LOCAL_MASTER_BROWSER(work))
- {
- /* Do a name query for the local master browser on this net. */
- query_name( subrec, work->work_group, 0x1d,
- check_for_master_browser_success,
- check_for_master_browser_fail,
- NULL);
- }
- }
- }
-}
-
-/*******************************************************************
- Run an election.
-******************************************************************/
-
-void run_elections(time_t t)
-{
- static time_t lastime = 0;
-
- struct subnet_record *subrec;
-
- /* Send election packets once every 2 seconds - note */
- if (lastime && (t - lastime < 2))
- return;
-
- lastime = t;
-
- START_PROFILE(run_elections);
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
-
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- if (work->RunningElection)
- {
- /*
- * We can only run an election for a workgroup if we have
- * registered the WORKGROUP<1e> name, as that's the name
- * we must listen to.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, work->work_group, 0x1e);
- if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
- DEBUG(8,("run_elections: Cannot send election packet yet as name %s not \
-yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
- continue;
- }
-
- send_election_dgram(subrec, work->work_group, work->ElectionCriterion,
- t - StartupTime, lp_netbios_name());
-
- if (work->ElectionCount++ >= 4)
- {
- /* Won election (4 packets were sent out uncontested. */
- DEBUG(2,("run_elections: >>> Won election for workgroup %s on subnet %s <<<\n",
- work->work_group, subrec->subnet_name ));
-
- work->RunningElection = False;
-
- become_local_master_browser(subrec, work);
- }
- }
- }
- }
- END_PROFILE(run_elections);
-}
-
-/*******************************************************************
- Determine if I win an election.
-******************************************************************/
-
-static BOOL win_election(struct work_record *work, int version,
- uint32 criterion, int timeup, char *server_name)
-{
- int mytimeup = time(NULL) - StartupTime;
- uint32 mycriterion = work->ElectionCriterion;
-
- /* If local master is false then never win
- in election broadcasts. */
- if(!lp_local_master())
- {
- DEBUG(3,("win_election: Losing election as local master == False\n"));
- return False;
- }
-
- DEBUG(4,("win_election: election comparison: %x:%x %x:%x %d:%d %s:%s\n",
- version, ELECTION_VERSION,
- criterion, mycriterion,
- timeup, mytimeup,
- server_name, lp_netbios_name()));
-
- if (version > ELECTION_VERSION)
- return(False);
- if (version < ELECTION_VERSION)
- return(True);
-
- if (criterion > mycriterion)
- return(False);
- if (criterion < mycriterion)
- return(True);
-
- if (timeup > mytimeup)
- return(False);
- if (timeup < mytimeup)
- return(True);
-
- if (strcasecmp(lp_netbios_name(), server_name) > 0)
- return(False);
-
- return(True);
-}
-
-/*******************************************************************
- Process an incoming election datagram packet.
-******************************************************************/
-
-void process_election(struct subnet_record *subrec, struct packet_struct *p, char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- int version = CVAL(buf,0);
- uint32 criterion = IVAL(buf,1);
- int timeup = IVAL(buf,5)/1000;
- char *server_name = buf+13;
- struct work_record *work;
- char *workgroup_name = dgram->dest_name.name;
-
- START_PROFILE(election);
- server_name[15] = 0;
-
- DEBUG(3,("process_election: Election request from %s at IP %s on subnet %s for workgroup %s.\n",
- server_name,inet_ntoa(p->ip), subrec->subnet_name, workgroup_name ));
-
- DEBUG(5,("process_election: vers=%d criterion=%08x timeup=%d\n", version,criterion,timeup));
-
- if(( work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL)
- {
- DEBUG(0,("process_election: Cannot find workgroup %s on subnet %s.\n",
- workgroup_name, subrec->subnet_name ));
- goto done;
- }
-
- if (!strequal(work->work_group, lp_workgroup()))
- {
- DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \
-is not my workgroup.\n", work->work_group, subrec->subnet_name ));
- goto done;
- }
-
- if (win_election(work, version,criterion,timeup,server_name))
- {
- /* We take precedence over the requesting server. */
- if (!work->RunningElection)
- {
- /* We weren't running an election - start running one. */
-
- work->needelection = True;
- work->ElectionCount=0;
- }
-
- /* Note that if we were running an election for this workgroup on this
- subnet already, we just ignore the server we take precedence over. */
- }
- else
- {
- /* We lost. Stop participating. */
- work->needelection = False;
-
- if (work->RunningElection || AM_LOCAL_MASTER_BROWSER(work))
- {
- work->RunningElection = False;
- DEBUG(3,("process_election: >>> Lost election for workgroup %s on subnet %s <<<\n",
- work->work_group, subrec->subnet_name ));
- if (AM_LOCAL_MASTER_BROWSER(work))
- unbecome_local_master_browser(subrec, work, False);
- }
- }
-done:
- END_PROFILE(election);
-}
-
-/****************************************************************************
- This function looks over all the workgroups known on all the broadcast
- subnets and decides if a browser election is to be run on that workgroup.
- It returns True if any election packets need to be sent (this will then
- be done by run_elections().
-***************************************************************************/
-
-BOOL check_elections(void)
-{
- struct subnet_record *subrec;
- BOOL run_any_election = False;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- run_any_election |= work->RunningElection;
-
- /*
- * Start an election if we have any chance of winning.
- * Note this is a change to the previous code, that would
- * only run an election if nmbd was in the potential browser
- * state. We need to run elections in any state if we're told
- * to. JRA.
- */
-
- if (work->needelection && !work->RunningElection && lp_local_master())
- {
- /*
- * We can only run an election for a workgroup if we have
- * registered the WORKGROUP<1e> name, as that's the name
- * we must listen to.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, work->work_group, 0x1e);
- if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
- DEBUG(8,("check_elections: Cannot send election packet yet as name %s not \
-yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
- continue;
- }
-
- DEBUG(3,("check_elections: >>> Starting election for workgroup %s on subnet %s <<<\n",
- work->work_group, subrec->subnet_name ));
-
- work->ElectionCount = 0;
- work->RunningElection = True;
- work->needelection = False;
- }
- }
- }
- return run_any_election;
-}
-
-
-
-/****************************************************************************
-process a internal Samba message forcing an election
-***************************************************************************/
-void nmbd_message_election(int msg_type, pid_t src, void *buf, size_t len)
-{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- struct work_record *work;
- for (work = subrec->workgrouplist; work; work = work->next) {
- if (strequal(work->work_group, lp_workgroup())) {
- work->needelection = True;
- work->ElectionCount=0;
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- }
- }
- }
-}
diff --git a/source4/nmbd/nmbd_incomingdgrams.c b/source4/nmbd/nmbd_incomingdgrams.c
deleted file mode 100644
index 3000c347d8..0000000000
--- a/source4/nmbd/nmbd_incomingdgrams.c
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-extern BOOL found_lm_clients;
-
-#if 0
-
-/* XXXX note: This function is currently unsuitable for use, as it
- does not properly check that a server is in a fit state to become
- a backup browser before asking it to be one.
- The code is left here to be worked on at a later date.
-*/
-
-/****************************************************************************
-Tell a server to become a backup browser
-**************************************************************************/
-
-void tell_become_backup(void)
-{
- struct subnet_record *subrec;
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- struct server_record *servrec;
- int num_servers = 0;
- int num_backups = 0;
-
- for (servrec = work->serverlist; servrec; servrec = servrec->next)
- {
- num_servers++;
-
- if (is_myname(servrec->serv.name))
- continue;
-
- if (servrec->serv.type & SV_TYPE_BACKUP_BROWSER)
- {
- num_backups++;
- continue;
- }
-
- if (servrec->serv.type & SV_TYPE_MASTER_BROWSER)
- continue;
-
- if (!(servrec->serv.type & SV_TYPE_POTENTIAL_BROWSER))
- continue;
-
- DEBUG(3,("num servers: %d num backups: %d\n",
- num_servers, num_backups));
-
- /* make first server a backup server. thereafter make every
- tenth server a backup server */
- if (num_backups != 0 && (num_servers+9) / num_backups > 10)
- continue;
-
- DEBUG(2,("sending become backup to %s %s for %s\n",
- servrec->serv.name, inet_ntoa(subrec->bcast_ip),
- work->work_group));
-
- /* type 11 request from MYNAME(20) to WG(1e) for SERVER */
- do_announce_request(servrec->serv.name, work->work_group,
- ANN_BecomeBackup, 0x20, 0x1e, subrec->bcast_ip);
- }
- }
- }
-}
-#endif
-
-/*******************************************************************
- Process an incoming host announcement packet.
-*******************************************************************/
-
-void process_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- int ttl = IVAL(buf,1)/1000;
- char *announce_name = buf+5;
- uint32 servertype = IVAL(buf,23);
- char *comment = buf+31;
- struct work_record *work;
- struct server_record *servrec;
- const char *work_name;
- char *source_name = dgram->source_name.name;
-
- START_PROFILE(host_announce);
- comment[43] = 0;
-
- DEBUG(3,("process_host_announce: from %s<%02x> IP %s to \
-%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),announce_name));
-
- DEBUG(5,("process_host_announce: ttl=%d server type=%08x comment=%s\n",
- ttl, servertype,comment));
-
- /* Filter servertype to remove impossible bits. */
- servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
-
- /* A host announcement must be sent to the name WORKGROUP<1d>. */
- if(dgram->dest_name.name_type != 0x1d)
- {
- DEBUG(2,("process_host_announce: incorrect name type for destination from IP %s \
-(was %02x) should be 0x1d. Allowing packet anyway.\n",
- inet_ntoa(p->ip), dgram->dest_name.name_type));
- /* Change it so it was. */
- dgram->dest_name.name_type = 0x1d;
- }
-
- /* For a host announce the workgroup name is the destination name. */
- work_name = dgram->dest_name.name;
-
- /*
- * Syntax servers version 5.1 send HostAnnounce packets to
- * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
- * instead of WORKGROUP<1d> name. So to fix this we check if
- * the workgroup name is our own name, and if so change it
- * to be our primary workgroup name.
- */
-
- if(strequal(work_name, lp_netbios_name()))
- work_name = lp_workgroup();
-
- /*
- * We are being very agressive here in adding a workgroup
- * name on the basis of a host announcing itself as being
- * in that workgroup. Maybe we should wait for the workgroup
- * announce instead ? JRA.
- */
-
- work = find_workgroup_on_subnet(subrec, work_name);
-
- if(servertype != 0)
- {
- if (work ==NULL )
- {
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- goto done;
- }
-
- if((servrec = find_server_in_workgroup( work, announce_name))==NULL)
- {
- /* If this server is not already in the workgroup, add it. */
- create_server_on_workgroup(work, announce_name,
- servertype|SV_TYPE_LOCAL_LIST_ONLY,
- ttl, comment);
- }
- else
- {
- /* Update the record. */
- servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
- update_server_ttl( servrec, ttl);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
- }
- }
- else
- {
- /*
- * This server is announcing it is going down. Remove it from the
- * workgroup.
- */
- if(!is_myname(announce_name) && (work != NULL) &&
- ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)
- )
- {
- remove_server_from_workgroup( work, servrec);
- }
- }
- subrec->work_changed = True;
-done:
- END_PROFILE(host_announce);
-}
-
-/*******************************************************************
- Process an incoming WORKGROUP announcement packet.
-*******************************************************************/
-
-void process_workgroup_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- int ttl = IVAL(buf,1)/1000;
- char *workgroup_announce_name = buf+5;
- uint32 servertype = IVAL(buf,23);
- char *master_name = buf+31;
- struct work_record *work;
- char *source_name = dgram->source_name.name;
-
- START_PROFILE(workgroup_announce);
- master_name[43] = 0;
-
- DEBUG(3,("process_workgroup_announce: from %s<%02x> IP %s to \
-%s for workgroup %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),workgroup_announce_name));
-
- DEBUG(5,("process_workgroup_announce: ttl=%d server type=%08x master browser=%s\n",
- ttl, servertype, master_name));
-
- /* Workgroup announcements must only go to the MSBROWSE name. */
- if (!strequal(dgram->dest_name.name, MSBROWSE) || (dgram->dest_name.name_type != 0x1))
- {
- DEBUG(0,("process_workgroup_announce: from IP %s should be to __MSBROWSE__<0x01> not %s\n",
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- goto done;
- }
-
- if ((work = find_workgroup_on_subnet(subrec, workgroup_announce_name))==NULL)
- {
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, workgroup_announce_name, ttl))==NULL)
- goto done;
- }
- else
- {
- /* Update the workgroup death_time. */
- update_workgroup_ttl(work, ttl);
- }
-
- if(*work->local_master_browser_name == '\0')
- {
- /* Set the master browser name. */
- set_workgroup_local_master_browser_name( work, master_name );
- }
-
- subrec->work_changed = True;
-done:
- END_PROFILE(workgroup_announce);
-}
-
-/*******************************************************************
- Process an incoming local master browser announcement packet.
-*******************************************************************/
-
-void process_local_master_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- int ttl = IVAL(buf,1)/1000;
- char *server_name = buf+5;
- uint32 servertype = IVAL(buf,23);
- char *comment = buf+31;
- char *work_name;
- struct work_record *work;
- struct server_record *servrec;
- char *source_name = dgram->source_name.name;
-
- START_PROFILE(local_master_announce);
- comment[43] = 0;
-
- DEBUG(3,("process_local_master_announce: from %s<%02x> IP %s to \
-%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),server_name));
-
- DEBUG(5,("process_local_master_announce: ttl=%d server type=%08x comment=%s\n",
- ttl, servertype, comment));
-
- /* A local master announcement must be sent to the name WORKGROUP<1e>. */
- if(dgram->dest_name.name_type != 0x1e)
- {
- DEBUG(0,("process_local_master_announce: incorrect name type for destination from IP %s \
-(was %02x) should be 0x1e. Ignoring packet.\n",
- inet_ntoa(p->ip), dgram->dest_name.name_type));
- goto done;
- }
-
- /* Filter servertype to remove impossible bits. */
- servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
-
- /* For a local master announce the workgroup name is the destination name. */
- work_name = dgram->dest_name.name;
-
- if ((work = find_workgroup_on_subnet(subrec, work_name))==NULL)
- {
- /* Don't bother adding if it's a local master release announce. */
- if(servertype == 0)
- goto done;
-
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- goto done;
- }
-
- /* If we think we're the local master browser for this workgroup,
- we should never have got this packet. We don't see our own
- packets.
- */
- if(AM_LOCAL_MASTER_BROWSER(work))
- {
- DEBUG(0,("process_local_master_announce: Server %s at IP %s is announcing itself as \
-a local master browser for workgroup %s and we think we are master. Forcing election.\n",
- server_name, inet_ntoa(p->ip), work_name));
-
- /* Samba nmbd versions 1.9.17 to 1.9.17p4 have a bug in that when
- they have become a local master browser once, they will never
- stop sending local master announcements. To fix this we send
- them a reset browser packet, with level 0x2 on the __SAMBA__
- name that only they should be listening to. */
-
- send_browser_reset( 0x2, "__SAMBA__" , 0x20, p->ip);
-
- /* We should demote ourself and force an election. */
-
- unbecome_local_master_browser( subrec, work, True);
-
- /* The actual election requests are handled in
- nmbd_election.c */
- goto done;
- }
-
- /* Find the server record on this workgroup. If it doesn't exist, add it. */
-
- if(servertype != 0)
- {
- if((servrec = find_server_in_workgroup( work, server_name))==NULL)
- {
- /* If this server is not already in the workgroup, add it. */
- create_server_on_workgroup(work, server_name,
- servertype|SV_TYPE_LOCAL_LIST_ONLY,
- ttl, comment);
- }
- else
- {
- /* Update the record. */
- servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
- update_server_ttl(servrec, ttl);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
- }
-
- set_workgroup_local_master_browser_name( work, server_name );
- }
- else
- {
- /*
- * This server is announcing it is going down. Remove it from the
- * workgroup.
- */
- if(!is_myname(server_name) && (work != NULL) &&
- ((servrec = find_server_in_workgroup( work, server_name))!=NULL)
- )
- {
- remove_server_from_workgroup( work, servrec);
- }
- }
-
- subrec->work_changed = True;
-done:
- END_PROFILE(local_master_announce);
-}
-
-/*******************************************************************
- Process a domain master announcement frame.
- Domain master browsers receive these from local masters. The Domain
- master should then issue a sync with the local master, asking for
- that machines local server list.
-******************************************************************/
-
-void process_master_browser_announce(struct subnet_record *subrec,
- struct packet_struct *p,char *buf)
-{
- char *local_master_name = buf;
- struct work_record *work;
- struct browse_cache_record *browrec;
-
- START_PROFILE(master_browser_announce);
- local_master_name[15] = 0;
-
- DEBUG(3,("process_master_browser_announce: Local master announce from %s IP %s.\n",
- local_master_name, inet_ntoa(p->ip)));
-
- if (!lp_domain_master())
- {
- DEBUG(0,("process_master_browser_announce: Not configured as domain \
-master - ignoring master announce.\n"));
- goto done;
- }
-
- if((work = find_workgroup_on_subnet(subrec, lp_workgroup())) == NULL)
- {
- DEBUG(0,("process_master_browser_announce: Cannot find workgroup %s on subnet %s\n",
- lp_workgroup(), subrec->subnet_name));
- goto done;
- }
-
- if(!AM_DOMAIN_MASTER_BROWSER(work))
- {
- DEBUG(0,("process_master_browser_announce: Local master announce made to us from \
-%s IP %s and we are not a domain master browser.\n", local_master_name, inet_ntoa(p->ip)));
- goto done;
- }
-
- /* Add this host as a local master browser entry on the browse lists.
- This causes a sync request to be made to it at a later date.
- */
-
- if((browrec = find_browser_in_lmb_cache( local_master_name )) == NULL)
- {
- /* Add it. */
- create_browser_in_lmb_cache( work->work_group, local_master_name, p->ip);
- }
- else
- update_browser_death_time(browrec);
-done:
- END_PROFILE(master_browser_announce);
-}
-
-/*******************************************************************
- Process an incoming LanMan host announcement packet.
-*******************************************************************/
-
-void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- uint32 servertype = IVAL(buf,1);
- int osmajor=CVAL(buf,5); /* major version of node software */
- int osminor=CVAL(buf,6); /* minor version of node software */
- int ttl = SVAL(buf,7);
- char *announce_name = buf+9;
- struct work_record *work;
- struct server_record *servrec;
- const char *work_name;
- char *source_name = dgram->source_name.name;
- pstring comment;
- char *s = buf+9;
-
- START_PROFILE(lm_host_announce);
- s = skip_string(s,1);
- StrnCpy(comment, s, 43);
-
- DEBUG(3,("process_lm_host_announce: LM Announcement from %s<%02x> IP %s to \
-%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),announce_name));
-
- DEBUG(5,("process_lm_host_announce: os=(%d,%d) ttl=%d server type=%08x comment=%s\n",
- osmajor, osminor, ttl, servertype,comment));
-
- if ((osmajor < 36) || (osmajor > 38) || (osminor !=0))
- {
- DEBUG(5,("process_lm_host_announce: LM Announcement packet does not \
-originate from OS/2 Warp client. Ignoring packet.\n"));
- /* Could have been from a Windows machine (with its LM Announce enabled),
- or a Samba server. Then don't disrupt the current browse list. */
- goto done;
- }
-
- /* Filter servertype to remove impossible bits. */
- servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
-
- /* A LanMan host announcement must be sent to the name WORKGROUP<00>. */
- if(dgram->dest_name.name_type != 0x00)
- {
- DEBUG(2,("process_lm_host_announce: incorrect name type for destination from IP %s \
-(was %02x) should be 0x00. Allowing packet anyway.\n",
- inet_ntoa(p->ip), dgram->dest_name.name_type));
- /* Change it so it was. */
- dgram->dest_name.name_type = 0x00;
- }
-
- /* For a LanMan host announce the workgroup name is the destination name. */
- work_name = dgram->dest_name.name;
-
- /*
- * Syntax servers version 5.1 send HostAnnounce packets to
- * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
- * instead of WORKGROUP<1d> name. So to fix this we check if
- * the workgroup name is our own name, and if so change it
- * to be our primary workgroup name. This code is probably
- * not needed in the LanMan announce code, but it won't hurt.
- */
-
- if(strequal(work_name, lp_netbios_name()))
- work_name = lp_workgroup();
-
- /*
- * We are being very agressive here in adding a workgroup
- * name on the basis of a host announcing itself as being
- * in that workgroup. Maybe we should wait for the workgroup
- * announce instead ? JRA.
- */
-
- work = find_workgroup_on_subnet(subrec, work_name);
-
- if(servertype != 0)
- {
- if (work == NULL)
- {
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- goto done;
- }
-
- if((servrec = find_server_in_workgroup( work, announce_name))==NULL)
- {
- /* If this server is not already in the workgroup, add it. */
- create_server_on_workgroup(work, announce_name,
- servertype|SV_TYPE_LOCAL_LIST_ONLY,
- ttl, comment);
- }
- else
- {
- /* Update the record. */
- servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
- update_server_ttl( servrec, ttl);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
- }
- }
- else
- {
- /*
- * This server is announcing it is going down. Remove it from the
- * workgroup.
- */
- if(!is_myname(announce_name) && (work != NULL) &&
- ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)
- )
- {
- remove_server_from_workgroup( work, servrec);
- }
- }
-
- subrec->work_changed = True;
- found_lm_clients = True;
-done:
- END_PROFILE(lm_host_announce);
-}
-
-/****************************************************************************
- Send a backup list response.
-*****************************************************************************/
-static void send_backup_list_response(struct subnet_record *subrec,
- struct work_record *work,
- struct nmb_name *send_to_name,
- unsigned char max_number_requested,
- uint32 token, struct in_addr sendto_ip,
- int port)
-{
- char outbuf[1024];
- char *p, *countptr;
- unsigned int count = 0;
-#if 0
- struct server_record *servrec;
-#endif
-
- memset(outbuf,'\0',sizeof(outbuf));
-
- DEBUG(3,("send_backup_list_response: sending backup list for workgroup %s to %s IP %s\n",
- work->work_group, nmb_namestr(send_to_name), inet_ntoa(sendto_ip)));
-
- p = outbuf;
-
- SCVAL(p,0,ANN_GetBackupListResp); /* Backup list response opcode. */
- p++;
-
- countptr = p;
- p++;
-
- SIVAL(p,0,token); /* The sender's unique info. */
- p += 4;
-
- /* We always return at least one name - our own. */
- count = 1;
- StrnCpy(p,lp_netbios_name(),15);
- strupper(p);
- p = skip_string(p,1);
-
- /* Look for backup browsers in this workgroup. */
-
-#if 0
- /* we don't currently send become_backup requests so we should never
- send any other servers names out as backups for our
- workgroup. That's why this is commented out (tridge) */
-
- /*
- * NB. Note that the struct work_record here is not neccessarily
- * attached to the subnet *subrec.
- */
-
- for (servrec = work->serverlist; servrec; servrec = servrec->next)
- {
- int len = PTR_DIFF(p, outbuf);
- if((sizeof(outbuf) - len) < 16)
- break;
-
- if(count >= (unsigned int)max_number_requested)
- break;
-
- if(strnequal(servrec->serv.name, lp_netbios_name(),15))
- continue;
-
- if(!(servrec->serv.type & SV_TYPE_BACKUP_BROWSER))
- continue;
-
- StrnCpy(p, servrec->serv.name, 15);
- strupper(p);
- count++;
-
- DEBUG(5,("send_backup_list_response: Adding server %s number %d\n",
- p, count));
-
- p = skip_string(p,1);
- }
-#endif
-
- SCVAL(countptr, 0, count);
-
- DEBUG(4,("send_backup_list_response: sending response to %s<00> IP %s with %d servers.\n",
- send_to_name->name, inet_ntoa(sendto_ip), count));
-
- send_mailslot(True, BROWSE_MAILSLOT,
- outbuf,PTR_DIFF(p,outbuf),
- lp_netbios_name(), 0,
- send_to_name->name,0,
- sendto_ip, subrec->myip, port);
-}
-
-/*******************************************************************
- Process a send backup list request packet.
-
- A client sends a backup list request to ask for a list of servers on
- the net that maintain server lists for a domain. A server is then
- chosen from this list to send NetServerEnum commands to to list
- available servers.
-
-********************************************************************/
-
-void process_get_backup_list_request(struct subnet_record *subrec,
- struct packet_struct *p,char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct work_record *work;
- unsigned char max_number_requested = CVAL(buf,0);
- uint32 token = IVAL(buf,1); /* Sender's key index for the workgroup. */
- int name_type = dgram->dest_name.name_type;
- char *workgroup_name = dgram->dest_name.name;
- struct subnet_record *search_subrec = subrec;
-
- START_PROFILE(get_backup_list);
- DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name)));
-
- /* We have to be a master browser, or a domain master browser
- for the requested workgroup. That means it must be our
- workgroup. */
-
- if(strequal(workgroup_name, lp_workgroup()) == False)
- {
- DEBUG(7,("process_get_backup_list_request: Ignoring announce request for workgroup %s.\n",
- workgroup_name));
- goto done;
- }
-
- if((work = find_workgroup_on_subnet(search_subrec, workgroup_name)) == NULL)
- {
- DEBUG(0,("process_get_backup_list_request: Cannot find workgroup %s on \
-subnet %s.\n", workgroup_name, search_subrec->subnet_name));
- goto done;
- }
-
- /*
- * If the packet was sent to WORKGROUP<1b> instead
- * of WORKGROUP<1d> then it was unicast to us a domain master
- * browser. Change search subrec to unicast.
- */
-
- if(name_type == 0x1b)
- {
- /* We must be a domain master browser in order to
- process this packet. */
-
- if(!AM_DOMAIN_MASTER_BROWSER(work))
- {
- DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
-and I am not a domain master browser.\n", workgroup_name));
- goto done;
- }
-
- search_subrec = unicast_subnet;
- }
- else if (name_type == 0x1d)
- {
- /* We must be a local master browser in order to
- process this packet. */
-
- if(!AM_LOCAL_MASTER_BROWSER(work))
- {
- DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
-and I am not a local master browser.\n", workgroup_name));
- goto done;
- }
- }
- else
- {
- DEBUG(0,("process_get_backup_list_request: Invalid name type %x - should be 0x1b or 0x1d.\n",
- name_type));
- goto done;
- }
-
- send_backup_list_response(subrec, work, &dgram->source_name,
- max_number_requested, token, p->ip, p->port);
-done:
- END_PROFILE(get_backup_list);
-}
-
-/*******************************************************************
- Process a reset browser state packet.
-
- Diagnostic packet:
- 0x1 - Stop being a master browser and become a backup browser.
- 0x2 - Discard browse lists, stop being a master browser, try again.
- 0x4 - Stop being a master browser forever.
-
-******************************************************************/
-
-void process_reset_browser(struct subnet_record *subrec,
- struct packet_struct *p,char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- int state = CVAL(buf,0);
- struct subnet_record *sr;
-
- START_PROFILE(reset_browser);
- DEBUG(1,("process_reset_browser: received diagnostic browser reset \
-request from %s IP %s state=0x%X\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), state));
-
- /* Stop being a local master browser on all our broadcast subnets. */
- if (state & 0x1)
- {
- for (sr = FIRST_SUBNET; sr; sr = NEXT_SUBNET_EXCLUDING_UNICAST(sr))
- {
- struct work_record *work;
- for (work = sr->workgrouplist; work; work = work->next)
- {
- if (AM_LOCAL_MASTER_BROWSER(work))
- unbecome_local_master_browser(sr, work, True);
- }
- }
- }
-
- /* Discard our browse lists. */
- if (state & 0x2)
- {
- /*
- * Calling expire_workgroups_and_servers with a -1
- * time causes all servers not marked with a PERMANENT_TTL
- * on the workgroup lists to be discarded, and all
- * workgroups with empty server lists to be discarded.
- * This means we keep our own server names and workgroup
- * as these have a PERMANENT_TTL.
- */
-
- expire_workgroups_and_servers(-1);
- }
-
- /* Request to stop browsing altogether. */
- if (state & 0x4)
- DEBUG(1,("process_reset_browser: ignoring request to stop being a browser.\n"));
-
- END_PROFILE(reset_browser);
-}
-
-/*******************************************************************
- Process an announcement request packet.
- We don't respond immediately, we just check it's a request for
- our workgroup and then set the flag telling the announce code
- in nmbd_sendannounce.c:announce_my_server_names that an
- announcement is needed soon.
-******************************************************************/
-
-void process_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct work_record *work;
- char *workgroup_name = dgram->dest_name.name;
-
- START_PROFILE(announce_request);
- DEBUG(3,("process_announce_request: Announce request from %s IP %s to %s.\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name)));
-
- /* We only send announcement requests on our workgroup. */
- if(strequal(workgroup_name, lp_workgroup()) == False)
- {
- DEBUG(7,("process_announce_request: Ignoring announce request for workgroup %s.\n",
- workgroup_name));
- goto done;
- }
-
- if((work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL)
- {
- DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
- workgroup_name));
- goto done;
- }
-
- work->needannounce = True;
-done:
- END_PROFILE(lm_host_announce);
-}
-
-/*******************************************************************
- Process a LanMan announcement request packet.
- We don't respond immediately, we just check it's a request for
- our workgroup and then set the flag telling that we have found
- a LanMan client (DOS or OS/2) and that we will have to start
- sending LanMan announcements (unless specifically disabled
- through the "lm announce" parameter in smb.conf)
-******************************************************************/
-
-void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- char *workgroup_name = dgram->dest_name.name;
-
- START_PROFILE(lm_announce_request);
- DEBUG(3,("process_lm_announce_request: Announce request from %s IP %s to %s.\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name)));
-
- /* We only send announcement requests on our workgroup. */
- if(strequal(workgroup_name, lp_workgroup()) == False)
- {
- DEBUG(7,("process_lm_announce_request: Ignoring announce request for workgroup %s.\n",
- workgroup_name));
- goto done;
- }
-
- if(find_workgroup_on_subnet(subrec, workgroup_name) == NULL)
- {
- DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
- workgroup_name));
- goto done;
- }
-
- found_lm_clients = True;
-done:
- END_PROFILE(lm_host_announce);
-}
diff --git a/source4/nmbd/nmbd_incomingrequests.c b/source4/nmbd/nmbd_incomingrequests.c
deleted file mode 100644
index 916f7763f2..0000000000
--- a/source4/nmbd/nmbd_incomingrequests.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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.
-
- This file contains all the code to process NetBIOS requests coming
- in on port 137. It does not deal with the code needed to service
- WINS server requests, but only broadcast and unicast requests.
-
-*/
-
-#include "includes.h"
-
-/****************************************************************************
-Send a name release response.
-**************************************************************************/
-
-static void send_name_release_response(int rcode, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
-
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_REL, /* nmbd type code. */
- NMB_NAME_RELEASE_OPCODE, /* opcode. */
- 0, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
-}
-
-/****************************************************************************
-Process a name release packet on a broadcast subnet.
-Ignore it if it's not one of our names.
-****************************************************************************/
-
-void process_name_release_request(struct subnet_record *subrec,
- struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct in_addr owner_ip;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct name_record *namerec;
- int rcode = 0;
-
- putip((char *)&owner_ip,&nmb->additional->rdata[2]);
-
- if(!bcast)
- {
- /* We should only get broadcast name release packets here.
- Anyone trying to release unicast should be going to a WINS
- server. If the code gets here, then either we are not a wins
- server and they sent it anyway, or we are a WINS server and
- the request was malformed. Either way, log an error here.
- and send an error reply back.
- */
- DEBUG(0,("process_name_release_request: unicast name release request \
-received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));
-
- send_name_release_response(FMT_ERR, p);
- return;
- }
-
- DEBUG(3,("process_name_release_request: Name release on name %s, \
-subnet %s from owner IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- subrec->subnet_name, inet_ntoa(owner_ip)));
-
- /* If someone is releasing a broadcast group name, just ignore it. */
- if( group && !ismyip(owner_ip) )
- return;
-
- /*
- * Code to work around a bug in FTP OnNet software NBT implementation.
- * They do a broadcast name release for WORKGROUP<0> and WORKGROUP<1e>
- * names and *don't set the group bit* !!!!!
- */
-
- if( !group && !ismyip(owner_ip) && strequal(question->name, lp_workgroup()) &&
- ((question->name_type == 0x0) || (question->name_type == 0x1e)))
- {
- DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \
-group release name %s from IP %s on subnet %s with no group bit set.\n",
- nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name ));
- return;
- }
-
- namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_ANY_NAME);
-
- /* We only care about someone trying to release one of our names. */
- if( namerec
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) ) )
- {
- rcode = ACT_ERR;
- DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \
-on subnet %s being rejected as it is one of our names.\n",
- nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
- }
-
- if(rcode == 0)
- return;
-
- /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
- send_name_release_response(rcode, p);
-}
-
-/****************************************************************************
-Send a name registration response.
-**************************************************************************/
-
-static void send_name_registration_response(int rcode, int ttl, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
-
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_REG, /* nmbd type code. */
- NMB_NAME_REG_OPCODE, /* opcode. */
- ttl, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
-}
-
-/****************************************************************************
-Process a name refresh request on a broadcast subnet.
-**************************************************************************/
-
-void process_name_refresh_request(struct subnet_record *subrec,
- struct packet_struct *p)
-{
-
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- struct in_addr from_ip;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(!bcast)
- {
- /* We should only get broadcast name refresh packets here.
- Anyone trying to refresh unicast should be going to a WINS
- server. If the code gets here, then either we are not a wins
- server and they sent it anyway, or we are a WINS server and
- the request was malformed. Either way, log an error here.
- and send an error reply back.
- */
- DEBUG(0,("process_name_refresh_request: unicast name registration request \
-received for name %s from IP %s on subnet %s.\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- DEBUG(0,("Error - should be sent to WINS server\n"));
-
- send_name_registration_response(FMT_ERR, 0, p);
- return;
- }
-
- /* Just log a message. We really don't care about broadcast name
- refreshes. */
-
- DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
-IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
-
-}
-
-/****************************************************************************
-Process a name registration request on a broadcast subnet.
-**************************************************************************/
-
-void process_name_registration_request(struct subnet_record *subrec,
- struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct name_record *namerec = NULL;
- int ttl = nmb->additional->ttl;
- struct in_addr from_ip;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(!bcast)
- {
- /* We should only get broadcast name registration packets here.
- Anyone trying to register unicast should be going to a WINS
- server. If the code gets here, then either we are not a wins
- server and they sent it anyway, or we are a WINS server and
- the request was malformed. Either way, log an error here.
- and send an error reply back.
- */
- DEBUG(0,("process_name_registration_request: unicast name registration request \
-received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
-
- send_name_registration_response(FMT_ERR, 0, p);
- return;
- }
-
- DEBUG(3,("process_name_registration_request: Name registration for name %s \
-IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
-
- /* See if the name already exists. */
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /*
- * If the name being registered exists and is a WINS_PROXY_NAME
- * then delete the WINS proxy name entry so we don't reply erroneously
- * later to queries.
- */
-
- if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME))
- {
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- }
-
- if (!group)
- {
- /* Unique name. */
-
- if( (namerec != NULL)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME)
- || NAME_GROUP(namerec) ) )
- {
- /* No-one can register one of Samba's names, nor can they
- register a name that's a group name as a unique name */
-
- send_name_registration_response(ACT_ERR, 0, p);
- return;
- }
- else if(namerec != NULL)
- {
- /* Update the namelist record with the new information. */
- namerec->data.ip[0] = from_ip;
- update_name_ttl(namerec, ttl);
-
- DEBUG(3,("process_name_registration_request: Updated name record %s \
-with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
- }
- else
- {
- /* Group name. */
-
- if( (namerec != NULL)
- && !NAME_GROUP(namerec)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) ) )
- {
- /* Disallow group names when we have a unique name. */
- send_name_registration_response(ACT_ERR, 0, p);
- return;
- }
- }
-}
-
-/****************************************************************************
-This is used to sort names for a name status into a sensible order.
-We put our own names first, then in alphabetical order.
-**************************************************************************/
-
-static int status_compare(char *n1,char *n2)
-{
- int l1,l2,l3;
-
- /* It's a bit tricky because the names are space padded */
- for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++) ;
- for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++) ;
- l3 = strlen(lp_netbios_name());
-
- if ((l1==l3) && strncmp(n1,lp_netbios_name(),l3) == 0 &&
- (l2!=l3 || strncmp(n2,lp_netbios_name(),l3) != 0))
- return -1;
-
- if ((l2==l3) && strncmp(n2,lp_netbios_name(),l3) == 0 &&
- (l1!=l3 || strncmp(n1,lp_netbios_name(),l3) != 0))
- return 1;
-
- return memcmp(n1,n2,18);
-}
-
-
-/****************************************************************************
- Process a node status query
- ****************************************************************************/
-
-void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- char *qname = nmb->question.question_name.name;
- int ques_type = nmb->question.question_name.name_type;
- char rdata[MAX_DGRAM_SIZE];
- char *countptr, *buf, *bufend, *buf0;
- int names_added,i;
- struct name_record *namerec;
-
- DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
-subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip),
- subrec->subnet_name));
-
- if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name,
- FIND_SELF_NAME)) == 0)
- {
- DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \
-subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
- inet_ntoa(p->ip), subrec->subnet_name));
-
- return;
- }
-
- /* this is not an exact calculation. the 46 is for the stats buffer
- and the 60 is to leave room for the header etc */
- bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60);
- countptr = buf = rdata;
- buf += 1;
- buf0 = buf;
-
- names_added = 0;
-
- namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
-
- while (buf < bufend)
- {
- if( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) )
- {
- int name_type = namerec->name.name_type;
-
- if (!strequal(namerec->name.name,"*") &&
- !strequal(namerec->name.name,"__SAMBA__") &&
- (name_type < 0x1b || name_type >= 0x20 ||
- ques_type < 0x1b || ques_type >= 0x20 ||
- strequal(qname, namerec->name.name)))
- {
- /* Start with the name. */
- memset(buf,'\0',18);
- slprintf(buf, 17, "%-15.15s",namerec->name.name);
- strupper(buf);
-
- /* Put the name type and netbios flags in the buffer. */
- buf[15] = name_type;
- set_nb_flags( &buf[16],namerec->data.nb_flags );
- buf[16] |= NB_ACTIVE; /* all our names are active */
-
- buf += 18;
-
- names_added++;
- }
- }
-
- /* Remove duplicate names. */
- if (names_added > 1) {
- qsort( buf0, names_added, 18, QSORT_CAST status_compare );
- }
-
- for( i=1; i < names_added ; i++ )
- {
- if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0)
- {
- names_added--;
- if (names_added == i)
- break;
- memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
- i--;
- }
- }
-
- buf = buf0 + 18*names_added;
-
- namerec = (struct name_record *)ubi_trNext( namerec );
-
- if (!namerec)
- {
- /* End of the subnet specific name list. Now
- add the names on the unicast subnet . */
- struct subnet_record *uni_subrec = unicast_subnet;
-
- if (uni_subrec != subrec)
- {
- subrec = uni_subrec;
- namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- }
- }
- if (!namerec)
- break;
-
- }
-
- SCVAL(countptr,0,names_added);
-
- /* We don't send any stats as they could be used to attack
- the protocol. */
- memset(buf,'\0',46);
-
- buf += 46;
-
- /* Send a NODE STATUS RESPONSE */
- reply_netbios_packet(p, /* Packet to reply to. */
- 0, /* Result code. */
- NMB_STATUS, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- 0, /* ttl. */
- rdata, /* data to send. */
- PTR_DIFF(buf,rdata)); /* data length. */
-}
-
-
-/***************************************************************************
-Process a name query.
-
-For broadcast name queries:
-
- - Only reply if the query is for one of YOUR names.
- - NEVER send a negative response to a broadcast query.
-
-****************************************************************************/
-
-void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- int name_type = question->name_type;
- BOOL bcast = nmb->header.nm_flags.bcast;
- int ttl=0;
- int rcode = 0;
- char *prdata = NULL;
- char rdata[6];
- BOOL success = False;
- struct name_record *namerec = NULL;
- int reply_data_len = 0;
- int i;
-
- DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n",
- inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
-
- /* Look up the name in the cache - if the request is a broadcast request that
- came from a subnet we don't know about then search all the broadcast subnets
- for a match (as we don't know what interface the request came in on). */
-
- if(subrec == remote_broadcast_subnet)
- namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
- else
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /* Check if it is a name that expired */
- if (namerec &&
- ((namerec->data.death_time != PERMANENT_TTL) &&
- (namerec->data.death_time < p->timestamp))) {
- DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
- namerec = NULL;
- }
-
- if (namerec) {
- /*
- * Always respond to unicast queries.
- * Don't respond to broadcast queries unless the query is for
- * a name we own, a Primary Domain Controller name, or a WINS_PROXY
- * name with type 0 or 0x20. WINS_PROXY names are only ever added
- * into the namelist if we were configured as a WINS proxy.
- */
-
- if (!bcast ||
- (bcast && ((name_type == 0x1b) ||
- (namerec->data.source == SELF_NAME) ||
- (namerec->data.source == PERMANENT_NAME) ||
- ((namerec->data.source == WINS_PROXY_NAME) &&
- ((name_type == 0) || (name_type == 0x20)))))) {
- /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY,
- or it's a Domain Master type. */
-
- /*
- * If this is a WINS_PROXY_NAME, then ceck that none of the IP
- * addresses we are returning is on the same broadcast subnet
- * as the requesting packet. If it is then don't reply as the
- * actual machine will be replying also and we don't want two
- * replies to a broadcast query.
- */
-
- if (namerec->data.source == WINS_PROXY_NAME) {
- for( i = 0; i < namerec->data.num_ips; i++) {
- if (same_net(namerec->data.ip[i], subrec->myip, subrec->mask_ip)) {
- DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also on the same subnet (%s) as the requestor. Not replying.\n",
- nmb_namestr(&namerec->name), subrec->subnet_name ));
- return;
- }
- }
- }
-
- ttl = (namerec->data.death_time != PERMANENT_TTL) ?
- namerec->data.death_time - p->timestamp : lp_max_ttl();
-
- /* Copy all known ip addresses into the return data. */
- /* Optimise for the common case of one IP address so
- we don't need a malloc. */
-
- if (namerec->data.num_ips == 1) {
- prdata = rdata;
- } else {
- if ((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL) {
- DEBUG(0,("process_name_query_request: malloc fail !\n"));
- return;
- }
- }
-
- for (i = 0; i < namerec->data.num_ips; i++) {
- set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
- putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
- }
-
- sort_query_replies(prdata, i, p->ip);
-
- reply_data_len = namerec->data.num_ips * 6;
- success = True;
- }
- }
-
- /*
- * If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
- * set we should initiate a WINS query here. On success we add the resolved name
- * into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
- */
-
- if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() &&
- bcast && (subrec != remote_broadcast_subnet)) {
- make_wins_proxy_name_query_request( subrec, p, question );
- return;
- }
-
- if (!success && bcast) {
- if(prdata != rdata)
- SAFE_FREE(prdata);
- return; /* Never reply with a negative response to broadcasts. */
- }
-
- /*
- * Final check. From observation, if a unicast packet is sent
- * to a non-WINS server with the recursion desired bit set
- * then never send a negative response.
- */
-
- if(!success && !bcast && nmb->header.nm_flags.recursion_desired) {
- if(prdata != rdata)
- SAFE_FREE(prdata);
- return;
- }
-
- if (success) {
- rcode = 0;
- DEBUG(3,("OK\n"));
- } else {
- rcode = NAM_ERR;
- DEBUG(3,("UNKNOWN\n"));
- }
-
- /* See rfc1002.txt 4.2.13. */
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- ttl, /* ttl. */
- prdata, /* data to send. */
- reply_data_len); /* data length. */
-
- if(prdata != rdata)
- SAFE_FREE(prdata);
-}
diff --git a/source4/nmbd/nmbd_lmhosts.c b/source4/nmbd/nmbd_lmhosts.c
deleted file mode 100644
index c47384c819..0000000000
--- a/source4/nmbd/nmbd_lmhosts.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Jeremy Allison 1994-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.
-
- Revision History:
-
- Handle lmhosts file reading.
-
-*/
-
-#include "includes.h"
-
-/****************************************************************************
-Load a lmhosts file.
-****************************************************************************/
-void load_lmhosts_file(char *fname)
-{
- char *name;
- int name_type;
- struct in_addr ipaddr;
- XFILE *fp = startlmhosts( fname );
- TALLOC_CTX *mem_ctx;
-
- if (!fp) {
- DEBUG(2,("load_lmhosts_file: Can't open lmhosts file %s. Error was %s\n",
- fname, strerror(errno)));
- return;
- }
- mem_ctx = talloc_init("load_lmhosts_files");
- if (!mem_ctx) {
- DEBUG(2,("load_lmhosts_file: No memory to open lmhosts file %s. Error was %s\n",
- fname, strerror(errno)));
- return;
- }
- while (getlmhostsent(mem_ctx, fp, name, &name_type, &ipaddr) )
- {
- struct subnet_record *subrec = NULL;
- enum name_source source = LMHOSTS_NAME;
-
- /* We find a relevent subnet to put this entry on, then add it. */
- /* Go through all the broadcast subnets and see if the mask matches. */
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- if(same_net(ipaddr, subrec->bcast_ip, subrec->mask_ip))
- break;
- }
-
- /* If none match add the name to the remote_broadcast_subnet. */
- if(subrec == NULL)
- subrec = remote_broadcast_subnet;
-
- if(name_type == -1)
- {
- /* Add the (0) and (0x20) names directly into the namelist for this subnet. */
- (void)add_name_to_subnet(subrec,name,0x00,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
- (void)add_name_to_subnet(subrec,name,0x20,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
- }
- else
- {
- /* Add the given name type to the subnet namelist. */
- (void)add_name_to_subnet(subrec,name,name_type,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
- }
- }
-
- endlmhosts(fp);
-}
-
-/****************************************************************************
- Find a name read from the lmhosts file. We secretly check the names on
- the remote_broadcast_subnet as if the name was added to a regular broadcast
- subnet it will be found by normal name query processing.
-****************************************************************************/
-
-BOOL find_name_in_lmhosts(struct nmb_name *nmbname, struct name_record **namerecp)
-{
- struct name_record *namerec;
-
- *namerecp = NULL;
-
- if((namerec = find_name_on_subnet(remote_broadcast_subnet, nmbname,
- FIND_ANY_NAME))==NULL)
- return False;
-
- if(!NAME_IS_ACTIVE(namerec) || (namerec->data.source != LMHOSTS_NAME))
- return False;
-
- *namerecp = namerec;
- return True;
-}
diff --git a/source4/nmbd/nmbd_logonnames.c b/source4/nmbd/nmbd_logonnames.c
deleted file mode 100644
index 40edc68800..0000000000
--- a/source4/nmbd/nmbd_logonnames.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-extern struct in_addr allones_ip;
-
-extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
-
-/****************************************************************************
- Fail to become a Logon server on a subnet.
- ****************************************************************************/
-static void become_logon_server_fail(struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *fail_name)
-{
- struct work_record *work = find_workgroup_on_subnet(subrec, fail_name->name);
- struct server_record *servrec;
-
- if(!work)
- {
- DEBUG(0,("become_logon_server_fail: Error - cannot find \
-workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, lp_netbios_name())) == NULL)
- {
- DEBUG(0,("become_logon_server_fail: Error - cannot find server %s \
-in workgroup %s on subnet %s\n",
- lp_netbios_name(), fail_name->name, subrec->subnet_name));
- work->log_state = LOGON_NONE;
- return;
- }
-
- /* Set the state back to LOGON_NONE. */
- work->log_state = LOGON_NONE;
-
- servrec->serv.type &= ~SV_TYPE_DOMAIN_CTRL;
-
- DEBUG(0,("become_logon_server_fail: Failed to become a domain master for \
-workgroup %s on subnet %s. Couldn't register name %s.\n",
- work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
-
-}
-
-/****************************************************************************
- Become a Logon server on a subnet.
- ****************************************************************************/
-
-static void become_logon_server_success(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *registered_name,
- uint16 nb_flags,
- int ttl, struct in_addr registered_ip)
-{
- struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
- struct server_record *servrec;
-
- if(!work)
- {
- DEBUG(0,("become_logon_server_success: Error - cannot find \
-workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, lp_netbios_name())) == NULL)
- {
- DEBUG(0,("become_logon_server_success: Error - cannot find server %s \
-in workgroup %s on subnet %s\n",
- lp_netbios_name(), registered_name->name, subrec->subnet_name));
- work->log_state = LOGON_NONE;
- return;
- }
-
- /* Set the state in the workgroup structure. */
- work->log_state = LOGON_SRV; /* Become domain master. */
-
- /* Update our server status. */
- servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER);
- /* To allow Win95 policies to load we need to set type domain
- controller.
- */
- servrec->serv.type |= SV_TYPE_DOMAIN_CTRL;
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- /*
- * Add the WORKGROUP<1C> name to the UNICAST subnet with the IP address
- * for this subnet so we will respond to queries on this name.
- */
- {
- struct nmb_name nmbname;
- make_nmb_name(&nmbname,lp_workgroup(),0x1c);
- insert_permanent_name_into_unicast(subrec, &nmbname, 0x1c);
- }
-
- DEBUG(0,("become_logon_server_success: Samba is now a logon server \
-for workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
-}
-
-/*******************************************************************
- Become a logon server by attempting to register the WORKGROUP<1c>
- group name.
-******************************************************************/
-
-static void become_logon_server(struct subnet_record *subrec,
- struct work_record *work)
-{
- DEBUG(2,("become_logon_server: Atempting to become logon server for workgroup %s \
-on subnet %s\n", work->work_group,subrec->subnet_name));
-
- DEBUG(3,("become_logon_server: go to first stage: register %s<1c> name\n",
- work->work_group));
- work->log_state = LOGON_WAIT;
-
- register_name(subrec, work->work_group,0x1c,samba_nb_type|NB_GROUP,
- become_logon_server_success,
- become_logon_server_fail, NULL);
-}
-
-/*****************************************************************************
- Add the internet group <1c> logon names by unicast and broadcast.
- ****************************************************************************/
-void add_logon_names(void)
-{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
-
- if (work && (work->log_state == LOGON_NONE))
- {
- struct nmb_name nmbname;
- make_nmb_name(&nmbname,lp_workgroup(),0x1c);
-
- if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "add_domain_logon_names:\n" );
- dbgtext( "Attempting to become logon server " );
- dbgtext( "for workgroup %s ", lp_workgroup() );
- dbgtext( "on subnet %s\n", subrec->subnet_name );
- }
- become_logon_server(subrec, work);
- }
- }
- }
-}
diff --git a/source4/nmbd/nmbd_mynames.c b/source4/nmbd/nmbd_mynames.c
deleted file mode 100644
index dd66821839..0000000000
--- a/source4/nmbd/nmbd_mynames.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
-
-/****************************************************************************
- Fail funtion when registering my netbios names.
- **************************************************************************/
-
-static void my_name_register_failed(struct subnet_record *subrec,
- struct response_record *rrec, struct nmb_name *nmbname)
-{
- DEBUG(0,("my_name_register_failed: Failed to register my name %s on subnet %s.\n",
- nmb_namestr(nmbname), subrec->subnet_name));
-}
-
-
-/****************************************************************************
- Add my workgroup and my given names to one subnet
- Also add the magic Samba names.
- **************************************************************************/
-void register_my_workgroup_one_subnet(struct subnet_record *subrec)
-{
- int i;
-
- struct work_record *work;
-
- /* Create the workgroup on the subnet. */
- if((work = create_workgroup_on_subnet(subrec, lp_workgroup(),
- PERMANENT_TTL)) == NULL) {
- DEBUG(0,("register_my_workgroup_and_names: Failed to create my workgroup %s on subnet %s. \
-Exiting.\n", lp_workgroup(), subrec->subnet_name));
- return;
- }
-
- /* Each subnet entry, except for the wins_server_subnet has
- the magic Samba names. */
- add_samba_names_to_subnet(subrec);
-
- /* Register all our names including aliases. */
- for (i=0; my_netbios_names(i); i++) {
- register_name(subrec, my_netbios_names(i),0x20,samba_nb_type,
- NULL,
- my_name_register_failed, NULL);
- register_name(subrec, my_netbios_names(i),0x03,samba_nb_type,
- NULL,
- my_name_register_failed, NULL);
- register_name(subrec, my_netbios_names(i),0x00,samba_nb_type,
- NULL,
- my_name_register_failed, NULL);
- }
-
- /* Initiate election processing, register the workgroup names etc. */
- initiate_myworkgroup_startup(subrec, work);
-}
-
-/*******************************************************************
- Utility function to add a name to the unicast subnet, or add in
- our IP address if it already exists.
-******************************************************************/
-
-static void insert_refresh_name_into_unicast( struct subnet_record *subrec,
- struct nmb_name *nmbname, uint16 nb_type )
-{
- struct name_record *namerec;
-
- if (!we_are_a_wins_client()) {
- insert_permanent_name_into_unicast(subrec, nmbname, nb_type);
- return;
- }
-
- if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
- {
- /* The name needs to be created on the unicast subnet. */
- (void)add_name_to_subnet( unicast_subnet, nmbname->name,
- nmbname->name_type, nb_type,
- MIN(lp_max_ttl(), MAX_REFRESH_TIME), SELF_NAME, 1, &subrec->myip);
- }
- else
- {
- /* The name already exists on the unicast subnet. Add our local
- IP for the given broadcast subnet to the name. */
- add_ip_to_name_record( namerec, subrec->myip);
- }
-}
-
-/****************************************************************************
- Add my workgroup and my given names to the subnet lists.
- Also add the magic Samba names.
- **************************************************************************/
-
-BOOL register_my_workgroup_and_names(void)
-{
- struct subnet_record *subrec;
- int i;
-
- for(subrec = FIRST_SUBNET;
- subrec;
- subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- register_my_workgroup_one_subnet(subrec);
- }
-
- /* We still need to add the magic Samba
- names and the netbios names to the unicast subnet directly. This is
- to allow unicast node status requests and queries to still work
- in a broadcast only environment. */
-
- add_samba_names_to_subnet(unicast_subnet);
-
- for (i=0; my_netbios_names(i); i++)
- {
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- /*
- * Ensure all the IP addresses are added if we are multihomed.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, my_netbios_names(i),0x20);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
-
- make_nmb_name(&nmbname, my_netbios_names(i),0x3);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
-
- make_nmb_name(&nmbname, my_netbios_names(i),0x0);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
- }
- }
-
- /*
- * Add the WORKGROUP<0> and WORKGROUP<1e> group names to the unicast subnet
- * also for the same reasons.
- */
-
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- /*
- * Ensure all the IP addresses are added if we are multihomed.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, lp_workgroup(), 0x0);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
-
- make_nmb_name(&nmbname, lp_workgroup(), 0x1e);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
- }
-
- /*
- * We need to add the Samba names to the remote broadcast subnet,
- * as NT 4.x does directed broadcast requests to the *<0x0> name.
- */
- add_samba_names_to_subnet(remote_broadcast_subnet);
-
- return True;
-}
-
-/****************************************************************************
- Remove all the names we registered.
-**************************************************************************/
-void release_wins_names(void)
-{
- struct subnet_record *subrec = unicast_subnet;
- struct name_record *namerec, *nextnamerec;
-
- for (namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec;
- namerec = nextnamerec) {
- nextnamerec = (struct name_record *)ubi_trNext( namerec );
- if( (namerec->data.source == SELF_NAME)
- && !NAME_IS_DEREGISTERING(namerec) )
- release_name( subrec, namerec, standard_success_release,
- NULL, NULL);
- }
-}
-
-/*******************************************************************
- Refresh our registered names with WINS
- ******************************************************************/
-void refresh_my_names(time_t t)
-{
- struct name_record *namerec;
-
- if (wins_srv_count() < 1) return;
-
- for (namerec = (struct name_record *)ubi_trFirst(unicast_subnet->namelist);
- namerec;
- namerec = (struct name_record *)ubi_trNext(namerec)) {
- /* Each SELF name has an individual time to be refreshed. */
- if ((namerec->data.source == SELF_NAME) &&
- (namerec->data.refresh_time < t) &&
- (namerec->data.death_time != PERMANENT_TTL)) {
- /* We cheat here and pretend the refresh is going to be
- successful & update the refresh times. This stops
- multiple refresh calls being done. We actually
- deal with refresh failure in the fail_fn.
- */
- if (!is_refresh_already_queued(unicast_subnet, namerec)) {
- wins_refresh_name(namerec);
- }
- namerec->data.death_time = t + lp_max_ttl();
- namerec->data.refresh_time = t + MIN(lp_max_ttl()/2, MAX_REFRESH_TIME);
- }
- }
-}
diff --git a/source4/nmbd/nmbd_namelistdb.c b/source4/nmbd/nmbd_namelistdb.c
deleted file mode 100644
index 6653cdd24b..0000000000
--- a/source4/nmbd/nmbd_namelistdb.c
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-uint16 samba_nb_type = 0; /* samba's NetBIOS name type */
-
-
-/* ************************************************************************** **
- * Set Samba's NetBIOS name type.
- * ************************************************************************** **
- */
-void set_samba_nb_type(void)
- {
- if( lp_wins_support() || wins_srv_count() )
- samba_nb_type = NB_HFLAG; /* samba is a 'hybrid' node type. */
- else
- samba_nb_type = NB_BFLAG; /* samba is broadcast-only node type. */
- } /* set_samba_nb_type */
-
-/* ************************************************************************** **
- * Convert a NetBIOS name to upper case.
- * ************************************************************************** **
- */
-static void upcase_name( struct nmb_name *target, struct nmb_name *source )
- {
- int i;
-
- if( NULL != source )
- (void)memcpy( target, source, sizeof( struct nmb_name ) );
-
- strupper( target->name );
- strupper( target->scope );
-
- /* fudge... We're using a byte-by-byte compare, so we must be sure that
- * unused space doesn't have garbage in it.
- */
- for( i = strlen( target->name ); i < sizeof( target->name ); i++ )
- target->name[i] = '\0';
- for( i = strlen( target->scope ); i < sizeof( target->scope ); i++ )
- target->scope[i] = '\0';
- } /* upcase_name */
-
-/* ************************************************************************** **
- * Add a new or overwrite an existing namelist entry.
- * ************************************************************************** **
- */
-static void update_name_in_namelist( struct subnet_record *subrec,
- struct name_record *namerec )
- {
- struct name_record *oldrec = NULL;
-
- (void)ubi_trInsert( subrec->namelist, namerec, &(namerec->name), &oldrec );
- if( oldrec )
- {
- SAFE_FREE( oldrec->data.ip );
- SAFE_FREE( oldrec );
- }
- } /* update_name_in_namelist */
-
-/* ************************************************************************** **
- * Remove a name from the namelist.
- * ************************************************************************** **
- */
-void remove_name_from_namelist( struct subnet_record *subrec,
- struct name_record *namerec )
- {
- (void)ubi_trRemove( subrec->namelist, namerec );
-
- SAFE_FREE(namerec->data.ip);
-
- ZERO_STRUCTP(namerec);
- SAFE_FREE(namerec);
-
- subrec->namelist_changed = True;
- } /* remove_name_from_namelist */
-
-/* ************************************************************************** **
- * Find a name in a subnet.
- * ************************************************************************** **
- */
-struct name_record *find_name_on_subnet( struct subnet_record *subrec,
- struct nmb_name *nmbname,
- BOOL self_only )
- {
- struct nmb_name uc_name[1];
- struct name_record *name_ret;
-
- upcase_name( uc_name, nmbname );
- name_ret = (struct name_record *)ubi_trFind( subrec->namelist, uc_name );
- if( name_ret )
- {
- /* Self names only - these include permanent names. */
- if( self_only
- && (name_ret->data.source != SELF_NAME)
- && (name_ret->data.source != PERMANENT_NAME) )
- {
- DEBUG( 9,
- ( "find_name_on_subnet: on subnet %s - self name %s NOT FOUND\n",
- subrec->subnet_name, nmb_namestr(nmbname) ) );
- return( NULL );
- }
- DEBUG( 9, ("find_name_on_subnet: on subnet %s - found name %s source=%d\n",
- subrec->subnet_name, nmb_namestr(nmbname), name_ret->data.source) );
- return( name_ret );
- }
- DEBUG( 9,
- ( "find_name_on_subnet: on subnet %s - name %s NOT FOUND\n",
- subrec->subnet_name, nmb_namestr(nmbname) ) );
- return( NULL );
- } /* find_name_on_subnet */
-
-/* ************************************************************************** **
- * Find a name over all known broadcast subnets.
- * ************************************************************************** **
- */
-struct name_record *find_name_for_remote_broadcast_subnet(
- struct nmb_name *nmbname,
- BOOL self_only )
- {
- struct subnet_record *subrec;
- struct name_record *namerec = NULL;
-
- for( subrec = FIRST_SUBNET;
- subrec;
- subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
- {
- if( NULL != (namerec = find_name_on_subnet(subrec, nmbname, self_only)) )
- break;
- }
-
- return( namerec );
- } /* find_name_for_remote_broadcast_subnet */
-
-/* ************************************************************************** **
- * Update the ttl of an entry in a subnet name list.
- * ************************************************************************** **
- */
-void update_name_ttl( struct name_record *namerec, int ttl )
-{
- time_t time_now = time(NULL);
-
- if( namerec->data.death_time != PERMANENT_TTL )
- namerec->data.death_time = time_now + ttl;
-
- namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
-
- namerec->subnet->namelist_changed = True;
-} /* update_name_ttl */
-
-/* ************************************************************************** **
- * Add an entry to a subnet name list.
- * ************************************************************************** **
- */
-struct name_record *add_name_to_subnet( struct subnet_record *subrec,
- const char *name,
- int type,
- uint16 nb_flags,
- int ttl,
- enum name_source source,
- int num_ips,
- struct in_addr *iplist)
-{
- struct name_record *namerec;
- time_t time_now = time(NULL);
-
- namerec = (struct name_record *)malloc( sizeof(*namerec) );
- if( NULL == namerec )
- {
- DEBUG( 0, ( "add_name_to_subnet: malloc fail.\n" ) );
- return( NULL );
- }
-
- memset( (char *)namerec, '\0', sizeof(*namerec) );
- namerec->data.ip = (struct in_addr *)malloc( sizeof(struct in_addr)
- * num_ips );
- if( NULL == namerec->data.ip )
- {
- DEBUG( 0, ( "add_name_to_subnet: malloc fail when creating ip_flgs.\n" ) );
-
- ZERO_STRUCTP(namerec);
- SAFE_FREE(namerec);
- return NULL;
- }
-
- namerec->subnet = subrec;
-
- make_nmb_name(&namerec->name, name, type);
- upcase_name(&namerec->name, NULL );
-
- /* Enter the name as active. */
- namerec->data.nb_flags = nb_flags | NB_ACTIVE;
- namerec->data.wins_flags = WINS_ACTIVE;
-
- /* If it's our primary name, flag it as so. */
- if( strequal( my_netbios_names(0), name ) )
- namerec->data.nb_flags |= NB_PERM;
-
- /* Copy the IPs. */
- namerec->data.num_ips = num_ips;
- memcpy( (namerec->data.ip), iplist, num_ips * sizeof(struct in_addr) );
-
- /* Data source. */
- namerec->data.source = source;
-
- /* Setup the death_time and refresh_time. */
- if( ttl == PERMANENT_TTL )
- namerec->data.death_time = PERMANENT_TTL;
- else
- namerec->data.death_time = time_now + ttl;
-
- namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
-
- /* Now add the record to the name list. */
- update_name_in_namelist( subrec, namerec );
-
- DEBUG( 3, ( "add_name_to_subnet: Added netbios name %s with first IP %s \
-ttl=%d nb_flags=%2x to subnet %s\n",
- nmb_namestr( &namerec->name ),
- inet_ntoa( *iplist ),
- ttl,
- (unsigned int)nb_flags,
- subrec->subnet_name ) );
-
- subrec->namelist_changed = True;
-
- return(namerec);
-}
-
-/*******************************************************************
- Utility function automatically called when a name refresh or register
- succeeds. By definition this is a SELF_NAME (or we wouldn't be registering
- it).
- ******************************************************************/
-
-void standard_success_register(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname, uint16 nb_flags, int ttl,
- struct in_addr registered_ip)
-{
- struct name_record *namerec;
-
- namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
- if( NULL == namerec )
- (void)add_name_to_subnet( subrec, nmbname->name, nmbname->name_type,
- nb_flags, ttl, SELF_NAME, 1, &registered_ip );
- else
- update_name_ttl( namerec, ttl );
-}
-
-/*******************************************************************
- Utility function automatically called when a name refresh or register
- fails. Note that this is only ever called on a broadcast subnet with
- one IP address per name. This is why it can just delete the name
- without enumerating the IP adresses. JRA.
- ******************************************************************/
-
-void standard_fail_register( struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *nmbname )
-{
- struct name_record *namerec;
-
- namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
-
- DEBUG( 0, ( "standard_fail_register: Failed to register/refresh name %s \
-on subnet %s\n",
- nmb_namestr(nmbname), subrec->subnet_name) );
-
- /* Remove the name from the subnet. */
- if( namerec )
- remove_name_from_namelist(subrec, namerec);
-}
-
-/*******************************************************************
- Utility function to remove an IP address from a name record.
- ******************************************************************/
-
-static void remove_nth_ip_in_record( struct name_record *namerec, int ind)
-{
- if( ind != namerec->data.num_ips )
- memmove( (char *)(&namerec->data.ip[ind]),
- (char *)(&namerec->data.ip[ind+1]),
- ( namerec->data.num_ips - ind - 1) * sizeof(struct in_addr) );
-
- namerec->data.num_ips--;
- namerec->subnet->namelist_changed = True;
-}
-
-/*******************************************************************
- Utility function to check if an IP address exists in a name record.
- ******************************************************************/
-
-BOOL find_ip_in_name_record( struct name_record *namerec, struct in_addr ip )
-{
- int i;
-
- for(i = 0; i < namerec->data.num_ips; i++)
- if(ip_equal( namerec->data.ip[i], ip))
- return True;
-
- return False;
-}
-
-/*******************************************************************
- Utility function to add an IP address to a name record.
- ******************************************************************/
-
-void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip )
-{
- struct in_addr *new_list;
-
- /* Don't add one we already have. */
- if( find_ip_in_name_record( namerec, new_ip ) )
- return;
-
- new_list = (struct in_addr *)malloc( (namerec->data.num_ips + 1)
- * sizeof(struct in_addr) );
- if( NULL == new_list )
- {
- DEBUG(0,("add_ip_to_name_record: Malloc fail !\n"));
- return;
- }
-
- memcpy( (char *)new_list,
- (char *)namerec->data.ip,
- namerec->data.num_ips * sizeof(struct in_addr) );
- new_list[namerec->data.num_ips] = new_ip;
-
- SAFE_FREE(namerec->data.ip);
- namerec->data.ip = new_list;
- namerec->data.num_ips += 1;
-
- namerec->subnet->namelist_changed = True;
-}
-
-/*******************************************************************
- Utility function to remove an IP address from a name record.
- ******************************************************************/
-
-void remove_ip_from_name_record( struct name_record *namerec,
- struct in_addr remove_ip )
-{
- /* Try and find the requested ip address - remove it. */
- int i;
- int orig_num = namerec->data.num_ips;
-
- for(i = 0; i < orig_num; i++)
- if( ip_equal( remove_ip, namerec->data.ip[i]) )
- {
- remove_nth_ip_in_record( namerec, i);
- break;
- }
-}
-
-/*******************************************************************
- Utility function that release_name callers can plug into as the
- success function when a name release is successful. Used to save
- duplication of success_function code.
- ******************************************************************/
-
-void standard_success_release( struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- struct in_addr released_ip )
-{
- struct name_record *namerec;
-
- namerec = find_name_on_subnet( subrec, nmbname, FIND_ANY_NAME );
-
- if( namerec == NULL )
- {
- DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
-on subnet %s. Name was not found on subnet.\n",
- nmb_namestr(nmbname),
- inet_ntoa(released_ip),
- subrec->subnet_name) );
- return;
- }
- else
- {
- int orig_num = namerec->data.num_ips;
-
- remove_ip_from_name_record( namerec, released_ip );
-
- if( namerec->data.num_ips == orig_num )
- DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
-on subnet %s. This ip is not known for this name.\n",
- nmb_namestr(nmbname),
- inet_ntoa(released_ip),
- subrec->subnet_name ) );
- }
-
- if( namerec->data.num_ips == 0 )
- remove_name_from_namelist( subrec, namerec );
-}
-
-/*******************************************************************
- Expires old names in a subnet namelist.
- ******************************************************************/
-
-void expire_names_on_subnet(struct subnet_record *subrec, time_t t)
-{
- struct name_record *namerec;
- struct name_record *next_namerec;
-
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec;
- namerec = next_namerec )
- {
- next_namerec = (struct name_record *)ubi_trNext( namerec );
- if( (namerec->data.death_time != PERMANENT_TTL)
- && (namerec->data.death_time < t) )
- {
- if( namerec->data.source == SELF_NAME )
- {
- DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF \
-name %s\n",
- subrec->subnet_name, nmb_namestr(&namerec->name) ) );
- namerec->data.death_time += 300;
- namerec->subnet->namelist_changed = True;
- continue;
- }
- DEBUG(3,("expire_names_on_subnet: Subnet %s - removing expired name %s\n",
- subrec->subnet_name, nmb_namestr(&namerec->name)));
-
- remove_name_from_namelist( subrec, namerec );
- }
- }
-}
-
-/*******************************************************************
- Expires old names in all subnet namelists.
- ******************************************************************/
-
-void expire_names(time_t t)
-{
- struct subnet_record *subrec;
-
- for( subrec = FIRST_SUBNET;
- subrec;
- subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) )
- {
- expire_names_on_subnet( subrec, t );
- }
-}
-
-/****************************************************************************
- Add the magic samba names, useful for finding samba servers.
- These go directly into the name list for a particular subnet,
- without going through the normal registration process.
- When adding them to the unicast subnet, add them as a list of
- all broadcast subnet IP addresses.
-**************************************************************************/
-
-void add_samba_names_to_subnet( struct subnet_record *subrec )
-{
- struct in_addr *iplist = &subrec->myip;
- int num_ips = 1;
-
- /* These names are added permanently (ttl of zero) and will NOT be
- refreshed. */
-
- if( (subrec == unicast_subnet)
- || (subrec == wins_server_subnet)
- || (subrec == remote_broadcast_subnet) )
- {
- struct subnet_record *bcast_subrecs;
- int i;
- /* Create an IP list containing all our known subnets. */
-
- num_ips = iface_count();
- iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) );
- if( NULL == iplist )
- {
- DEBUG(0,("add_samba_names_to_subnet: Malloc fail !\n"));
- return;
- }
-
- for( bcast_subrecs = FIRST_SUBNET, i = 0;
- bcast_subrecs;
- bcast_subrecs = NEXT_SUBNET_EXCLUDING_UNICAST(bcast_subrecs), i++ )
- iplist[i] = bcast_subrecs->myip;
-
- }
-
- (void)add_name_to_subnet(subrec,"*",0x0,samba_nb_type, PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
- (void)add_name_to_subnet(subrec,"*",0x20,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
- (void)add_name_to_subnet(subrec,"__SAMBA__",0x20,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
- (void)add_name_to_subnet(subrec,"__SAMBA__",0x00,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
-
- if(iplist != &subrec->myip)
- SAFE_FREE(iplist);
-}
-
-/****************************************************************************
- Dump the contents of the namelists on all the subnets (including unicast)
- into a file. Initiated by SIGHUP - used to debug the state of the namelists.
-**************************************************************************/
-
-static void dump_subnet_namelist( struct subnet_record *subrec, XFILE *fp)
-{
- struct name_record *namerec;
- const char *src_type;
- struct tm *tm;
- int i;
-
- x_fprintf(fp, "Subnet %s\n----------------------\n", subrec->subnet_name);
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) )
- {
- x_fprintf(fp,"\tName = %s\t", nmb_namestr(&namerec->name));
- switch(namerec->data.source)
- {
- case LMHOSTS_NAME:
- src_type = "LMHOSTS_NAME";
- break;
- case WINS_PROXY_NAME:
- src_type = "WINS_PROXY_NAME";
- break;
- case REGISTER_NAME:
- src_type = "REGISTER_NAME";
- break;
- case SELF_NAME:
- src_type = "SELF_NAME";
- break;
- case DNS_NAME:
- src_type = "DNS_NAME";
- break;
- case DNSFAIL_NAME:
- src_type = "DNSFAIL_NAME";
- break;
- case PERMANENT_NAME:
- src_type = "PERMANENT_NAME";
- break;
- default:
- src_type = "unknown!";
- break;
- }
- x_fprintf(fp,"Source = %s\nb_flags = %x\t", src_type, namerec->data.nb_flags);
-
- if(namerec->data.death_time != PERMANENT_TTL)
- {
- tm = localtime(&namerec->data.death_time);
- x_fprintf(fp, "death_time = %s\t", asctime(tm));
- }
- else
- x_fprintf(fp, "death_time = PERMANENT\t");
-
- if(namerec->data.refresh_time != PERMANENT_TTL)
- {
- tm = localtime(&namerec->data.refresh_time);
- x_fprintf(fp, "refresh_time = %s\n", asctime(tm));
- }
- else
- x_fprintf(fp, "refresh_time = PERMANENT\n");
-
- x_fprintf(fp, "\t\tnumber of IPS = %d", namerec->data.num_ips);
- for(i = 0; i < namerec->data.num_ips; i++)
- x_fprintf(fp, "\t%s", inet_ntoa(namerec->data.ip[i]));
-
- x_fprintf(fp, "\n\n");
- }
-}
-
-/****************************************************************************
- Dump the contents of the namelists on all the subnets (including unicast)
- into a file. Initiated by SIGHUP - used to debug the state of the namelists.
-**************************************************************************/
-
-void dump_all_namelists(void)
-{
- XFILE *fp;
- struct subnet_record *subrec;
-
- fp = x_fopen(lock_path("namelist.debug"),O_WRONLY|O_CREAT|O_TRUNC, 0644);
-
- if (!fp)
- {
- DEBUG(0,("dump_all_namelists: Can't open file %s. Error was %s\n",
- "namelist.debug",strerror(errno)));
- return;
- }
-
- for( subrec = FIRST_SUBNET;
- subrec;
- subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) )
- dump_subnet_namelist( subrec, fp );
-
- if( !we_are_a_wins_client() )
- dump_subnet_namelist( unicast_subnet, fp );
-
- if( remote_broadcast_subnet->namelist != NULL )
- dump_subnet_namelist( remote_broadcast_subnet, fp );
-
- if( wins_server_subnet != NULL )
- dump_subnet_namelist( wins_server_subnet, fp );
- x_fclose( fp );
-}
diff --git a/source4/nmbd/nmbd_namequery.c b/source4/nmbd/nmbd_namequery.c
deleted file mode 100644
index 8995e9ac52..0000000000
--- a/source4/nmbd/nmbd_namequery.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-/****************************************************************************
- Deal with a response packet when querying a name.
-****************************************************************************/
-
-static void query_name_response( struct subnet_record *subrec,
- struct response_record *rrec,
- struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- BOOL success = False;
- struct nmb_name *question_name =
- &rrec->packet->packet.nmb.question.question_name;
- struct in_addr answer_ip;
-
- zero_ip(&answer_ip);
-
- /* Ensure we don't retry the query but leave the response record cleanup
- to the timeout code. We may get more answer responses in which case
- we should mark the name in conflict.. */
- rrec->repeat_count = 0;
-
- if(rrec->num_msgs == 1)
- {
- /* This is the first response. */
-
- if(nmb->header.opcode == NMB_WACK_OPCODE)
- {
- /* WINS server is telling us to wait. Pretend we didn't get
- the response but don't send out any more query requests. */
-
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "query_name_response: " );
- dbgtext( "WACK from WINS server %s ", inet_ntoa(p->ip) );
- dbgtext( "in querying name %s ", nmb_namestr(question_name) );
- dbgtext( "on subnet %s.\n", subrec->subnet_name );
- }
-
- rrec->repeat_count = 0;
- /* How long we should wait for. */
- rrec->repeat_time = p->timestamp + nmb->answers->ttl;
- rrec->num_msgs--;
- return;
- }
- else if(nmb->header.rcode != 0)
- {
- success = False;
-
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
- dbgtext( "- negative response from IP %s ", inet_ntoa(p->ip) );
- dbgtext( "for name %s. ", nmb_namestr(question_name) );
- dbgtext( "Error code was %d.\n", nmb->header.rcode );
- }
- }
- else
- {
- if (!nmb->answers)
- {
- dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
- dbgtext( "IP %s ", inet_ntoa(p->ip) );
- dbgtext( "returned a success response with no answer\n" );
- return;
- }
-
- success = True;
-
- putip((char *)&answer_ip,&nmb->answers->rdata[2]);
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
- dbgtext( "- positive response from IP %s ", inet_ntoa(p->ip) );
- dbgtext( "for name %s. ", nmb_namestr(question_name) );
- dbgtext( "IP of that name is %s\n", inet_ntoa(answer_ip) );
- }
-
- /* Interestingly, we could add these names to our namelists, and
- change nmbd to a model that checked its own name cache first,
- before sending out a query. This is a task for another day, though.
- */
- }
- }
- else if( rrec->num_msgs > 1)
- {
- if( DEBUGLVL( 0 ) )
- {
- if (nmb->answers)
- putip( (char *)&answer_ip, &nmb->answers->rdata[2] );
- dbgtext( "query_name_response: " );
- dbgtext( "Multiple (%d) responses ", rrec->num_msgs );
- dbgtext( "received for a query on subnet %s ", subrec->subnet_name );
- dbgtext( "for name %s.\nThis response ", nmb_namestr(question_name) );
- dbgtext( "was from IP %s, reporting ", inet_ntoa(p->ip) );
- dbgtext( "an IP address of %s.\n", inet_ntoa(answer_ip) );
- }
-
- /* We have already called the success or fail function, so we
- don't call again here. Leave the response record around in
- case we get more responses. */
-
- return;
- }
-
- if(success && rrec->success_fn)
- (*(query_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, answer_ip, nmb->answers);
- else if( rrec->fail_fn)
- (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, nmb->header.rcode);
-
-}
-
-/****************************************************************************
- Deal with a timeout when querying a name.
-****************************************************************************/
-
-static void query_name_timeout_response(struct subnet_record *subrec,
- struct response_record *rrec)
-{
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- /* We can only fail here, never succeed. */
- BOOL failed = True;
- struct nmb_name *question_name = &sent_nmb->question.question_name;
-
- if(rrec->num_msgs != 0)
- {
- /* We got at least one response, and have called the success/fail
- function already. */
-
- failed = False;
- }
-
- if(failed)
- {
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "query_name_timeout_response: No response to " );
- dbgtext( "query for name %s ", nmb_namestr(question_name) );
- dbgtext( "on subnet %s.\n", subrec->subnet_name );
- }
- if(rrec->fail_fn)
- (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, 0);
- }
-
- remove_response_record(subrec, rrec);
-}
-
-/****************************************************************************
- Lookup a name on our local namelists. We check the lmhosts file first. If the
- name is not there we look for the name on the given subnet.
-****************************************************************************/
-
-static BOOL query_local_namelists(struct subnet_record *subrec, struct nmb_name *nmbname,
- struct name_record **namerecp)
-{
- struct name_record *namerec;
-
- *namerecp = NULL;
-
- if(find_name_in_lmhosts(nmbname, namerecp))
- return True;
-
- if((namerec = find_name_on_subnet(subrec, nmbname, FIND_ANY_NAME))==NULL)
- return False;
-
- if( NAME_IS_ACTIVE(namerec)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == LMHOSTS_NAME) ) )
- {
- *namerecp = namerec;
- return True;
- }
- return False;
-}
-
-/****************************************************************************
- Try and query for a name.
-****************************************************************************/
-
-BOOL query_name(struct subnet_record *subrec, char *name, int type,
- query_name_success_function success_fn,
- query_name_fail_function fail_fn,
- struct userdata_struct *userdata)
-{
- struct nmb_name nmbname;
- struct name_record *namerec;
-
- make_nmb_name(&nmbname, name, type);
-
- /*
- * We need to check our local namelists first.
- * It may be an magic name, lmhosts name or just
- * a name we have registered.
- */
-
- if(query_local_namelists(subrec, &nmbname, &namerec) == True)
- {
- struct res_rec rrec;
- int i;
-
- memset((char *)&rrec, '\0', sizeof(struct res_rec));
-
- /* Fake up the needed res_rec just in case it's used. */
- rrec.rr_name = nmbname;
- rrec.rr_type = RR_TYPE_NB;
- rrec.rr_class = RR_CLASS_IN;
- rrec.ttl = PERMANENT_TTL;
- rrec.rdlength = namerec->data.num_ips * 6;
- if(rrec.rdlength > MAX_DGRAM_SIZE)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "query_name: nmbd internal error - " );
- dbgtext( "there are %d ip addresses ", namerec->data.num_ips );
- dbgtext( "for name %s.\n", nmb_namestr(&nmbname) );
- }
- return False;
- }
-
- for( i = 0; i < namerec->data.num_ips; i++)
- {
- set_nb_flags( &rrec.rdata[i*6], namerec->data.nb_flags );
- putip( &rrec.rdata[(i*6) + 2], (char *)&namerec->data.ip[i]);
- }
-
- /* Call the success function directly. */
- if(success_fn)
- (*(query_name_success_function)success_fn)(subrec, userdata, &nmbname, namerec->data.ip[0], &rrec);
- return False;
- }
-
- if(queue_query_name( subrec,
- query_name_response,
- query_name_timeout_response,
- success_fn,
- fail_fn,
- userdata,
- &nmbname) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "query_name: Failed to send packet " );
- dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) );
- }
- return True;
- }
- return False;
-}
-
-/****************************************************************************
- Try and query for a name from nmbd acting as a WINS server.
-****************************************************************************/
-
-BOOL query_name_from_wins_server(struct in_addr ip_to,
- char *name, int type,
- query_name_success_function success_fn,
- query_name_fail_function fail_fn,
- struct userdata_struct *userdata)
-{
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, name, type);
-
- if(queue_query_name_from_wins_server( ip_to,
- query_name_response,
- query_name_timeout_response,
- success_fn,
- fail_fn,
- userdata,
- &nmbname) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "query_name_from_wins_server: Failed to send packet " );
- dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) );
- }
- return True;
- }
- return False;
-}
diff --git a/source4/nmbd/nmbd_nameregister.c b/source4/nmbd/nmbd_nameregister.c
deleted file mode 100644
index 7bf2584053..0000000000
--- a/source4/nmbd/nmbd_nameregister.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-/* forward declarations */
-static void wins_next_registration(struct response_record *rrec);
-
-
-/****************************************************************************
- Deal with a response packet when registering one of our names.
-****************************************************************************/
-
-static void register_name_response(struct subnet_record *subrec,
- struct response_record *rrec, struct packet_struct *p)
-{
- /*
- * If we are registering broadcast, then getting a response is an
- * error - we do not have the name. If we are registering unicast,
- * then we expect to get a response.
- */
-
- struct nmb_packet *nmb = &p->packet.nmb;
- BOOL bcast = nmb->header.nm_flags.bcast;
- BOOL success = True;
- struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
- struct nmb_name *answer_name = &nmb->answers->rr_name;
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- int ttl = 0;
- uint16 nb_flags = 0;
- struct in_addr register_ip;
- fstring reg_name;
-
- putip(&register_ip,&sent_nmb->additional->rdata[2]);
- fstrcpy(reg_name, inet_ntoa(register_ip));
-
- if (subrec == unicast_subnet) {
- /* we know that this wins server is definately alive - for the moment! */
- wins_srv_alive(rrec->packet->ip, register_ip);
- }
-
- /* Sanity check. Ensure that the answer name in the incoming packet is the
- same as the requested name in the outgoing packet. */
-
- if(!question_name || !answer_name) {
- DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
- question_name ? "question_name" : "answer_name" ));
- return;
- }
-
- if(!nmb_name_equal(question_name, answer_name)) {
- DEBUG(0,("register_name_response: Answer name %s differs from question name %s.\n",
- nmb_namestr(answer_name), nmb_namestr(question_name)));
- return;
- }
-
- if(bcast) {
- /*
- * Special hack to cope with old Samba nmbd's.
- * Earlier versions of Samba (up to 1.9.16p11) respond
- * to a broadcast name registration of WORKGROUP<1b> when
- * they should not. Hence, until these versions are gone,
- * we should treat such errors as success for this particular
- * case only. jallison@whistle.com.
- */
-
-#if 1 /* OLD_SAMBA_SERVER_HACK */
- if((nmb->header.rcode == ACT_ERR) && strequal(lp_workgroup(), answer_name->name) &&
- (answer_name->name_type == 0x1b)) {
- /* Pretend we did not get this. */
- rrec->num_msgs--;
-
- DEBUG(5,("register_name_response: Ignoring broadcast response to registration of name %s due to old Samba server bug.\n",
- nmb_namestr(answer_name)));
- return;
- }
-#endif /* OLD_SAMBA_SERVER_HACK */
-
- /* Someone else has the name. Log the problem. */
- DEBUG(1,("register_name_response: Failed to register name %s IP %s on subnet %s via broadcast. Error code was %d. Reject came from IP %s\n",
- nmb_namestr(answer_name),
- reg_name,
- subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
- success = False;
- } else {
- /* Unicast - check to see if the response allows us to have the name. */
- if (nmb->header.opcode == NMB_WACK_OPCODE) {
- /* WINS server is telling us to wait. Pretend we didn't get
- the response but don't send out any more register requests. */
-
- DEBUG(5,("register_name_response: WACK from WINS server %s in registering name %s IP %s\n",
- inet_ntoa(p->ip), nmb_namestr(answer_name), reg_name));
-
- rrec->repeat_count = 0;
- /* How long we should wait for. */
- rrec->repeat_time = p->timestamp + nmb->answers->ttl;
- rrec->num_msgs--;
- return;
- } else if (nmb->header.rcode != 0) {
- /* Error code - we didn't get the name. */
- success = False;
-
- DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n",
- subrec==unicast_subnet?"WINS ":"",
- inet_ntoa(p->ip),
- nmb_namestr(answer_name),
- reg_name,
- nmb->header.rcode));
- } else {
- success = True;
- /* Get the data we need to pass to the success function. */
- nb_flags = get_nb_flags(nmb->answers->rdata);
- ttl = nmb->answers->ttl;
-
- /* send off a registration for the next IP, if any */
- wins_next_registration(rrec);
- }
- }
-
- DEBUG(5,("register_name_response: %s in registering %sname %s IP %s with %s.\n",
- success ? "success" : "failure",
- subrec==unicast_subnet?"WINS ":"",
- nmb_namestr(answer_name),
- reg_name,
- inet_ntoa(rrec->packet->ip)));
-
- if(success) {
- /* Enter the registered name into the subnet name database before calling
- the success function. */
- standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
- if( rrec->success_fn)
- (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
- } else {
- if( rrec->fail_fn)
- (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
- /* Remove the name. */
- standard_fail_register( subrec, rrec, question_name);
- }
-
- /* Ensure we don't retry. */
- remove_response_record(subrec, rrec);
-}
-
-
-/****************************************************************************
- Deal with a timeout of a WINS registration request
-****************************************************************************/
-static void wins_registration_timeout(struct subnet_record *subrec,
- struct response_record *rrec)
-{
- struct userdata_struct *userdata = rrec->userdata;
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- struct nmb_name *nmbname = &sent_nmb->question.question_name;
- struct in_addr register_ip;
- fstring src_addr;
-
- putip(&register_ip,&sent_nmb->additional->rdata[2]);
-
- fstrcpy(src_addr, inet_ntoa(register_ip));
-
- DEBUG(2,("wins_registration_timeout: WINS server %s timed out registering IP %s\n",
- inet_ntoa(rrec->packet->ip), src_addr));
-
- /* mark it temporarily dead for this source address */
- wins_srv_died(rrec->packet->ip, register_ip);
-
- /* if we have some userdata then use that to work out what
- wins server to try next */
- if (userdata) {
- const char *tag = (const char *)userdata->data;
-
- /* try the next wins server in our failover list for
- this tag */
- rrec->packet->ip = wins_srv_ip_tag(tag, register_ip);
- }
-
- /* if we have run out of wins servers for this tag then they
- must all have timed out. We treat this as *success*, not
- failure, and go into our standard name refresh mode. This
- copes with all the wins servers being down */
- if (wins_srv_is_dead(rrec->packet->ip, register_ip)) {
- uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
- int ttl = sent_nmb->additional->ttl;
-
- standard_success_register(subrec, userdata, nmbname, nb_flags, ttl, register_ip);
- if(rrec->success_fn) {
- (*(register_name_success_function)rrec->success_fn)(subrec,
- rrec->userdata,
- nmbname,
- nb_flags,
- ttl,
- register_ip);
- }
-
- /* send off a registration for the next IP, if any */
- wins_next_registration(rrec);
-
- /* don't need to send this packet any more */
- remove_response_record(subrec, rrec);
- return;
- }
-
- /* we will be moving to the next WINS server for this group,
- send it immediately */
- rrec->repeat_count = 2;
- rrec->repeat_time = time(NULL) + 1;
- rrec->in_expiration_processing = False;
-
- DEBUG(6,("Retrying register of name %s IP %s with WINS server %s\n",
- nmb_namestr(nmbname), src_addr, inet_ntoa(rrec->packet->ip)));
-
- /* notice that we don't remove the response record. This keeps
- us trying to register with each of our failover wins servers */
-}
-
-
-/****************************************************************************
- Deal with a timeout when registering one of our names.
-****************************************************************************/
-
-static void register_name_timeout_response(struct subnet_record *subrec,
- struct response_record *rrec)
-{
- /*
- * If we are registering unicast, then NOT getting a response is an
- * error - we do not have the name. If we are registering broadcast,
- * then we don't expect to get a response.
- */
-
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- BOOL bcast = sent_nmb->header.nm_flags.bcast;
- BOOL success = False;
- struct nmb_name *question_name = &sent_nmb->question.question_name;
- uint16 nb_flags = 0;
- int ttl = 0;
- struct in_addr registered_ip;
-
- if (bcast) {
- if(rrec->num_msgs == 0) {
- /* Not receiving a message is success for broadcast registration. */
- success = True;
-
- /* Pull the success values from the original request packet. */
- nb_flags = get_nb_flags(sent_nmb->additional->rdata);
- ttl = sent_nmb->additional->ttl;
- putip(&registered_ip,&sent_nmb->additional->rdata[2]);
- }
- } else {
- /* wins timeouts are special */
- wins_registration_timeout(subrec, rrec);
- return;
- }
-
- DEBUG(5,("register_name_timeout_response: %s in registering name %s on subnet %s.\n",
- success ? "success" : "failure", nmb_namestr(question_name), subrec->subnet_name));
- if(success) {
- /* Enter the registered name into the subnet name database before calling
- the success function. */
- standard_success_register(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
- if( rrec->success_fn)
- (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
- } else {
- if( rrec->fail_fn)
- (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
- /* Remove the name. */
- standard_fail_register( subrec, rrec, question_name);
- }
-
- /* Ensure we don't retry. */
- remove_response_record(subrec, rrec);
-}
-
-
-/****************************************************************************
-initiate one multi-homed name registration packet
-****************************************************************************/
-static void multihomed_register_one(struct nmb_name *nmbname,
- uint16 nb_flags,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn,
- struct in_addr ip,
- const char *tag)
-{
- struct userdata_struct *userdata;
- struct in_addr wins_ip = wins_srv_ip_tag(tag, ip);
- fstring ip_str;
-
- userdata = (struct userdata_struct *)malloc(sizeof(*userdata) + strlen(tag) + 1);
- if (!userdata) {
- DEBUG(0,("Failed to allocate userdata structure!\n"));
- return;
- }
- ZERO_STRUCTP(userdata);
- userdata->userdata_len = strlen(tag) + 1;
- strlcpy(userdata->data, tag, userdata->userdata_len);
-
- fstrcpy(ip_str, inet_ntoa(ip));
-
- DEBUG(6,("Registering name %s IP %s with WINS server %s using tag '%s'\n",
- nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
-
- if (queue_register_multihomed_name(unicast_subnet,
- register_name_response,
- register_name_timeout_response,
- success_fn,
- fail_fn,
- userdata,
- nmbname,
- nb_flags,
- ip,
- wins_ip) == NULL) {
- DEBUG(0,("multihomed_register_one: Failed to send packet trying to register name %s IP %s\n",
- nmb_namestr(nmbname), inet_ntoa(ip)));
- }
-
- free(userdata);
-}
-
-
-/****************************************************************************
-we have finished the registration of one IP and need to see if we have
-any more IPs left to register with this group of wins server for this name
-****************************************************************************/
-static void wins_next_registration(struct response_record *rrec)
-{
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- struct nmb_name *nmbname = &sent_nmb->question.question_name;
- uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
- struct userdata_struct *userdata = rrec->userdata;
- const char *tag;
- struct in_addr last_ip;
- struct subnet_record *subrec;
-
- putip(&last_ip,&sent_nmb->additional->rdata[2]);
-
- if (!userdata) {
- /* it wasn't multi-homed */
- return;
- }
-
- tag = (const char *)userdata->data;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- if (ip_equal(last_ip, subrec->myip)) {
- subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec);
- break;
- }
- }
-
- if (!subrec) {
- /* no more to do! */
- return;
- }
-
- switch (sent_nmb->header.opcode) {
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- multihomed_register_one(nmbname, nb_flags, NULL, NULL, subrec->myip, tag);
- break;
- case NMB_NAME_REFRESH_OPCODE_8:
- queue_wins_refresh(nmbname,
- register_name_response,
- register_name_timeout_response,
- nb_flags, subrec->myip, tag);
- break;
- }
-}
-
-/****************************************************************************
- Try and register one of our names on the unicast subnet - multihomed.
-****************************************************************************/
-static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn)
-{
- /*
- If we are adding a group name, we just send multiple
- register name packets to the WINS server (this is an
- internet group name.
-
- If we are adding a unique name, We need first to add
- our names to the unicast subnet namelist. This is
- because when a WINS server receives a multihomed
- registration request, the first thing it does is to
- send a name query to the registering machine, to see
- if it has put the name in it's local namelist.
- We need the name there so the query response code in
- nmbd_incomingrequests.c will find it.
-
- We are adding this name prematurely (we don't really
- have it yet), but as this is on the unicast subnet
- only we will get away with this (only the WINS server
- will ever query names from us on this subnet).
- */
- int num_ips=0;
- int i, t;
- struct subnet_record *subrec;
- char **wins_tags;
- struct in_addr *ip_list;
-
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
- num_ips++;
-
- if((ip_list = (struct in_addr *)malloc(num_ips * sizeof(struct in_addr)))==NULL) {
- DEBUG(0,("multihomed_register_name: malloc fail !\n"));
- return;
- }
-
- for (subrec = FIRST_SUBNET, i = 0;
- subrec;
- subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ ) {
- ip_list[i] = subrec->myip;
- }
-
- add_name_to_subnet(unicast_subnet, nmbname->name, nmbname->name_type,
- nb_flags, lp_max_ttl(), SELF_NAME,
- num_ips, ip_list);
-
- /* get the list of wins tags - we try to register for each of them */
- wins_tags = wins_srv_tags();
-
- /* Now try and register the name for each wins tag. Note that
- at this point we only register our first IP with each wins
- group. We will register the rest from
- wins_next_registration() when we get the reply for this
- one. That follows the way W2K does things (tridge)
- */
- for (t=0; wins_tags && wins_tags[t]; t++) {
- multihomed_register_one(nmbname, nb_flags,
- success_fn, fail_fn,
- ip_list[0],
- wins_tags[t]);
- }
-
- wins_srv_tags_free(wins_tags);
-
- SAFE_FREE(ip_list);
-}
-
-
-/****************************************************************************
- Try and register one of our names.
-****************************************************************************/
-void register_name(struct subnet_record *subrec,
- const char *name, int type, uint16 nb_flags,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn,
- struct userdata_struct *userdata)
-{
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, name, type);
-
- /* Always set the NB_ACTIVE flag on the name we are
- registering. Doesn't make sense without it.
- */
-
- nb_flags |= NB_ACTIVE;
-
- if (subrec == unicast_subnet) {
- /* we now always do multi-homed registration if we are
- registering to a WINS server. This copes much
- better with complex WINS setups */
- multihomed_register_name(&nmbname, nb_flags,
- success_fn, fail_fn);
- return;
- }
-
- if (queue_register_name(subrec,
- register_name_response,
- register_name_timeout_response,
- success_fn,
- fail_fn,
- userdata,
- &nmbname,
- nb_flags) == NULL) {
- DEBUG(0,("register_name: Failed to send packet trying to register name %s\n",
- nmb_namestr(&nmbname)));
- }
-}
-
-
-/****************************************************************************
- Try and refresh one of our names. This is *only* called for WINS refresh
-****************************************************************************/
-void wins_refresh_name(struct name_record *namerec)
-{
- int t;
- char **wins_tags;
-
- /* get the list of wins tags - we try to refresh for each of them */
- wins_tags = wins_srv_tags();
-
- for (t=0; wins_tags && wins_tags[t]; t++) {
- queue_wins_refresh(&namerec->name,
- register_name_response,
- register_name_timeout_response,
- namerec->data.nb_flags,
- namerec->data.ip[0], wins_tags[t]);
- }
-
- wins_srv_tags_free(wins_tags);
-}
diff --git a/source4/nmbd/nmbd_namerelease.c b/source4/nmbd/nmbd_namerelease.c
deleted file mode 100644
index 0611ca9323..0000000000
--- a/source4/nmbd/nmbd_namerelease.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-/****************************************************************************
- Deal with a response packet when releasing one of our names.
-****************************************************************************/
-
-static void release_name_response(struct subnet_record *subrec,
- struct response_record *rrec, struct packet_struct *p)
-{
- /*
- * If we are releasing broadcast, then getting a response is an
- * error. If we are releasing unicast, then we expect to get a response.
- */
- struct nmb_packet *nmb = &p->packet.nmb;
- BOOL bcast = nmb->header.nm_flags.bcast;
- BOOL success = True;
- struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
- struct nmb_name *answer_name = &nmb->answers->rr_name;
- struct in_addr released_ip;
-
- /* Sanity check. Ensure that the answer name in the incoming packet is the
- same as the requested name in the outgoing packet. */
- if (!nmb_name_equal(question_name, answer_name)) {
- DEBUG(0,("release_name_response: Answer name %s differs from question name %s.\n",
- nmb_namestr(answer_name), nmb_namestr(question_name)));
- return;
- }
-
- if (bcast) {
- /* Someone sent a response to a bcast release? ignore it. */
- return;
- }
-
- /* Unicast - check to see if the response allows us to release the name. */
- if (nmb->header.rcode != 0) {
- /* Error code - we were told not to release the name ! What now ! */
- success = False;
-
- DEBUG(0,("release_name_response: WINS server at IP %s rejected our \
-name release of name %s with error code %d.\n",
- inet_ntoa(p->ip),
- nmb_namestr(answer_name), nmb->header.rcode));
- } else if (nmb->header.opcode == NMB_WACK_OPCODE) {
- /* WINS server is telling us to wait. Pretend we didn't get
- the response but don't send out any more release requests. */
-
- DEBUG(5,("release_name_response: WACK from WINS server %s in releasing \
-name %s on subnet %s.\n",
- inet_ntoa(p->ip), nmb_namestr(answer_name), subrec->subnet_name));
-
- rrec->repeat_count = 0;
- /* How long we should wait for. */
- rrec->repeat_time = p->timestamp + nmb->answers->ttl;
- rrec->num_msgs--;
- return;
- }
-
- DEBUG(5,("release_name_response: %s in releasing name %s on subnet %s.\n",
- success ? "success" : "failure", nmb_namestr(answer_name), subrec->subnet_name));
- if (success) {
- putip((char*)&released_ip ,&nmb->answers->rdata[2]);
-
- if(rrec->success_fn)
- (*(release_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, released_ip);
- standard_success_release( subrec, rrec->userdata, answer_name, released_ip);
- } else {
- /* We have no standard_fail_release - maybe we should add one ? */
- if (rrec->fail_fn) {
- (*(release_name_fail_function)rrec->fail_fn)(subrec, rrec, answer_name);
- }
- }
-
- remove_response_record(subrec, rrec);
-}
-
-/****************************************************************************
- Deal with a timeout when releasing one of our names.
-****************************************************************************/
-
-static void release_name_timeout_response(struct subnet_record *subrec,
- struct response_record *rrec)
-{
- /* a release is *always* considered to be successful when it
- times out. This doesn't cause problems as if a WINS server
- doesn't respond and someone else wants the name then the
- normal WACK/name query from the WINS server will cope */
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- BOOL bcast = sent_nmb->header.nm_flags.bcast;
- struct nmb_name *question_name = &sent_nmb->question.question_name;
- struct in_addr released_ip;
-
- /* Get the ip address we were trying to release. */
- putip((char*)&released_ip ,&sent_nmb->additional->rdata[2]);
-
- if (!bcast) {
- /* mark the WINS server temporarily dead */
- wins_srv_died(rrec->packet->ip, released_ip);
- }
-
- DEBUG(5,("release_name_timeout_response: success in releasing name %s on subnet %s.\n",
- nmb_namestr(question_name), subrec->subnet_name));
-
- if (rrec->success_fn) {
- (*(release_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, released_ip);
- }
-
- standard_success_release( subrec, rrec->userdata, question_name, released_ip);
- remove_response_record(subrec, rrec);
-}
-
-
-/*
- when releasing a name with WINS we need to send the release to each of
- the WINS groups
-*/
-static void wins_release_name(struct name_record *namerec,
- release_name_success_function success_fn,
- release_name_fail_function fail_fn,
- struct userdata_struct *userdata)
-{
- int t, i;
- char **wins_tags;
-
- /* get the list of wins tags - we try to release for each of them */
- wins_tags = wins_srv_tags();
-
- for (t=0;wins_tags && wins_tags[t]; t++) {
- for (i = 0; i < namerec->data.num_ips; i++) {
- struct in_addr wins_ip = wins_srv_ip_tag(wins_tags[t], namerec->data.ip[i]);
-
- BOOL last_one = ((i==namerec->data.num_ips - 1) && !wins_tags[t+1]);
- if (queue_release_name(unicast_subnet,
- release_name_response,
- release_name_timeout_response,
- last_one?success_fn : NULL,
- last_one? fail_fn : NULL,
- last_one? userdata : NULL,
- &namerec->name,
- namerec->data.nb_flags,
- namerec->data.ip[i],
- wins_ip) == NULL) {
- DEBUG(0,("release_name: Failed to send packet trying to release name %s IP %s\n",
- nmb_namestr(&namerec->name), inet_ntoa(namerec->data.ip[i]) ));
- }
- }
- }
-
- wins_srv_tags_free(wins_tags);
-}
-
-
-/****************************************************************************
- Try and release one of our names.
-****************************************************************************/
-
-void release_name(struct subnet_record *subrec, struct name_record *namerec,
- release_name_success_function success_fn,
- release_name_fail_function fail_fn,
- struct userdata_struct *userdata)
-{
- int i;
-
- /* Ensure it's a SELF name, and in the ACTIVE state. */
- if ((namerec->data.source != SELF_NAME) || !NAME_IS_ACTIVE(namerec)) {
- DEBUG(0,("release_name: Cannot release name %s from subnet %s. Source was %d \n",
- nmb_namestr(&namerec->name), subrec->subnet_name, namerec->data.source));
- return;
- }
-
- /* Set the name into the deregistering state. */
- namerec->data.nb_flags |= NB_DEREG;
-
- /* wins releases are a bit different */
- if (subrec == unicast_subnet) {
- wins_release_name(namerec, success_fn, fail_fn, userdata);
- return;
- }
-
- /*
- * Go through and release the name for all known ip addresses.
- * Only call the success/fail function on the last one (it should
- * only be done once).
- */
- for (i = 0; i < namerec->data.num_ips; i++) {
- if (queue_release_name(subrec,
- release_name_response,
- release_name_timeout_response,
- (i == (namerec->data.num_ips - 1)) ? success_fn : NULL,
- (i == (namerec->data.num_ips - 1)) ? fail_fn : NULL,
- (i == (namerec->data.num_ips - 1)) ? userdata : NULL,
- &namerec->name,
- namerec->data.nb_flags,
- namerec->data.ip[i],
- subrec->bcast_ip) == NULL) {
- DEBUG(0,("release_name: Failed to send packet trying to release name %s IP %s\n",
- nmb_namestr(&namerec->name), inet_ntoa(namerec->data.ip[i]) ));
- }
- }
-}
diff --git a/source4/nmbd/nmbd_nodestatus.c b/source4/nmbd/nmbd_nodestatus.c
deleted file mode 100644
index 993e4d9d17..0000000000
--- a/source4/nmbd/nmbd_nodestatus.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-/****************************************************************************
- Deal with a successful node status response.
-****************************************************************************/
-static void node_status_response(struct subnet_record *subrec,
- struct response_record *rrec, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
- struct nmb_name *answer_name = &nmb->answers->rr_name;
-
- /* Sanity check. Ensure that the answer name in the incoming packet is the
- same as the requested name in the outgoing packet. */
-
- if(!nmb_name_equal(question_name, answer_name))
- {
- DEBUG(0,("node_status_response: Answer name %s differs from question \
-name %s.\n", nmb_namestr(answer_name), nmb_namestr(question_name)));
- return;
- }
-
- DEBUG(5,("node_status_response: response from name %s on subnet %s.\n",
- nmb_namestr(answer_name), subrec->subnet_name));
-
- /* Just send the whole answer resource record for the success function
- to parse. */
- if(rrec->success_fn)
- (*(node_status_success_function)rrec->success_fn)(subrec, rrec->userdata, nmb->answers, p->ip);
-
- /* Ensure we don't retry. */
- remove_response_record(subrec, rrec);
-}
-
-/****************************************************************************
- Deal with a timeout when requesting a node status.
-****************************************************************************/
-static void node_status_timeout_response(struct subnet_record *subrec,
- struct response_record *rrec)
-{
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- struct nmb_name *question_name = &sent_nmb->question.question_name;
-
- DEBUG(5,("node_status_timeout_response: failed to get node status from name %s on subnet %s\n",
- nmb_namestr(question_name), subrec->subnet_name));
-
- if( rrec->fail_fn)
- (*rrec->fail_fn)(subrec, rrec);
-
- /* Ensure we don't retry. */
- remove_response_record(subrec, rrec);
-}
-
-/****************************************************************************
- Try and do a node status to a name - given the name & IP address.
-****************************************************************************/
-
-BOOL node_status(struct subnet_record *subrec, struct nmb_name *nmbname,
- struct in_addr send_ip, node_status_success_function success_fn,
- node_status_fail_function fail_fn, struct userdata_struct *userdata)
-{
- if(queue_node_status( subrec,
- node_status_response, node_status_timeout_response,
- success_fn, fail_fn, userdata, nmbname, send_ip)==NULL)
- {
- DEBUG(0,("node_status: Failed to send packet trying to get node status for \
-name %s, IP address %s\n", nmb_namestr(nmbname), inet_ntoa(send_ip)));
- return True;
- }
- return False;
-}
diff --git a/source4/nmbd/nmbd_packets.c b/source4/nmbd/nmbd_packets.c
deleted file mode 100644
index 6ee13812dc..0000000000
--- a/source4/nmbd/nmbd_packets.c
+++ /dev/null
@@ -1,2013 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-extern int global_nmb_port;
-
-extern int num_response_packets;
-
-extern struct in_addr loopback_ip;
-
-static void queue_packet(struct packet_struct *packet);
-
-BOOL rescan_listen_set = False;
-
-
-/*******************************************************************
- The global packet linked-list. Incoming entries are
- added to the end of this list. It is supposed to remain fairly
- short so we won't bother with an end pointer.
-******************************************************************/
-
-static struct packet_struct *packet_queue = NULL;
-
-/***************************************************************************
-Utility function to find the specific fd to send a packet out on.
-**************************************************************************/
-
-static int find_subnet_fd_for_address( struct in_addr local_ip )
-{
- struct subnet_record *subrec;
-
- for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- if(ip_equal(local_ip, subrec->myip))
- return subrec->nmb_sock;
-
- return ClientNMB;
-}
-
-/***************************************************************************
-Utility function to find the specific fd to send a mailslot packet out on.
-**************************************************************************/
-
-static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
-{
- struct subnet_record *subrec;
-
- for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- if(ip_equal(local_ip, subrec->myip))
- return subrec->dgram_sock;
-
- return ClientDGRAM;
-}
-
-/***************************************************************************
-Get/Set problematic nb_flags as network byte order 16 bit int.
-**************************************************************************/
-
-uint16 get_nb_flags(char *buf)
-{
- return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
-}
-
-void set_nb_flags(char *buf, uint16 nb_flags)
-{
- *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
- *buf = '\0';
-}
-
-/***************************************************************************
-Dumps out the browse packet data.
-**************************************************************************/
-
-static void debug_browse_data(char *outbuf, int len)
-{
- int i,j;
-
- DEBUG( 4, ( "debug_browse_data():\n" ) );
- for (i = 0; i < len; i+= 16)
- {
- DEBUGADD( 4, ( "%3x char ", i ) );
-
- for (j = 0; j < 16; j++)
- {
- unsigned char x;
- if (i+j >= len)
- break;
-
- x = outbuf[i+j];
- if (x < 32 || x > 127)
- x = '.';
-
- DEBUGADD( 4, ( "%c", x ) );
- }
-
- DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
-
- for (j = 0; j < 16; j++)
- {
- if (i+j >= len)
- break;
- DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
- }
-
- DEBUGADD( 4, ("\n") );
- }
-}
-
-/***************************************************************************
- Generates the unique transaction identifier
-**************************************************************************/
-
-static uint16 name_trn_id=0;
-
-static uint16 generate_name_trn_id(void)
-{
-
- if (!name_trn_id)
- {
- name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
- }
- name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
- return name_trn_id;
-}
-
-/***************************************************************************
- Either loops back or sends out a completed NetBIOS packet.
-**************************************************************************/
-
-static BOOL send_netbios_packet(struct packet_struct *p)
-{
- BOOL loopback_this_packet = False;
-
- /* Check if we are sending to or from ourselves as a WINS server. */
- if(ismyip(p->ip) && (p->port == global_nmb_port))
- loopback_this_packet = True;
-
- if(loopback_this_packet)
- {
- struct packet_struct *lo_packet = NULL;
- DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
- if((lo_packet = copy_packet(p)) == NULL)
- return False;
- queue_packet(lo_packet);
- }
- else if (!send_packet(p))
- {
- DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
- inet_ntoa(p->ip),p->port));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
- Sets up the common elements of an outgoing NetBIOS packet.
-
- Note: do not attempt to rationalise whether rec_des should be set or not
- in a particular situation. Just follow rfc_1002 or look at examples from WinXX.
- It does NOT follow the rule that requests to the wins server always have
- rec_des true. See for example name releases and refreshes
-**************************************************************************/
-
-static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
- BOOL bcast, BOOL rec_des,
- struct in_addr to_ip)
-{
- struct packet_struct *packet = NULL;
- struct nmb_packet *nmb = NULL;
-
- /* Allocate the packet_struct we will return. */
- if((packet = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
- {
- DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
- return NULL;
- }
-
- memset((char *)packet,'\0',sizeof(*packet));
-
- nmb = &packet->packet.nmb;
-
- nmb->header.name_trn_id = generate_name_trn_id();
- nmb->header.response = False;
- nmb->header.nm_flags.recursion_desired = rec_des;
- nmb->header.nm_flags.recursion_available = False;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = False;
- nmb->header.nm_flags.bcast = bcast;
-
- nmb->header.rcode = 0;
- nmb->header.qdcount = 1;
- nmb->header.ancount = 0;
- nmb->header.nscount = 0;
-
- nmb->question.question_name = *nmbname;
- nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
- nmb->question.question_class = QUESTION_CLASS_IN;
-
- packet->ip = to_ip;
- packet->port = NMB_PORT;
- packet->fd = ClientNMB;
- packet->timestamp = time(NULL);
- packet->packet_type = NMB_PACKET;
- packet->locked = False;
-
- return packet; /* Caller must free. */
-}
-
-/***************************************************************************
- Sets up the common elements of register, refresh or release packet.
-**************************************************************************/
-
-static BOOL create_and_init_additional_record(struct packet_struct *packet,
- uint16 nb_flags,
- struct in_addr *register_ip)
-{
- struct nmb_packet *nmb = &packet->packet.nmb;
-
- if((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) {
- DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
- return False;
- }
-
- memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
-
- nmb->additional->rr_name = nmb->question.question_name;
- nmb->additional->rr_type = RR_TYPE_NB;
- nmb->additional->rr_class = RR_CLASS_IN;
-
- /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
- if (nmb->header.nm_flags.bcast)
- nmb->additional->ttl = PERMANENT_TTL;
- else
- nmb->additional->ttl = lp_max_ttl();
-
- nmb->additional->rdlength = 6;
-
- set_nb_flags(nmb->additional->rdata,nb_flags);
-
- /* Set the address for the name we are registering. */
- putip(&nmb->additional->rdata[2], register_ip);
-
- /*
- it turns out that Jeremys code was correct, we are supposed
- to send registrations from the IP we are registering. The
- trick is what to do on timeouts! When we send on a
- non-routable IP then the reply will timeout, and we should
- treat this as success, not failure. That means we go into
- our standard refresh cycle for that name which copes nicely
- with disconnected networks.
- */
- packet->fd = find_subnet_fd_for_address(*register_ip);
-
- return True;
-}
-
-/***************************************************************************
- Sends out a name query.
-**************************************************************************/
-
-static BOOL initiate_name_query_packet( struct packet_struct *packet)
-{
- struct nmb_packet *nmb = NULL;
-
- nmb = &packet->packet.nmb;
-
- nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
- nmb->header.arcount = 0;
-
- nmb->header.nm_flags.recursion_desired = True;
-
- DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
-
- return send_netbios_packet( packet );
-}
-
-/***************************************************************************
- Sends out a name query - from a WINS server.
-**************************************************************************/
-
-static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
-{
- struct nmb_packet *nmb = NULL;
-
- nmb = &packet->packet.nmb;
-
- nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
- nmb->header.arcount = 0;
-
- nmb->header.nm_flags.recursion_desired = False;
-
- DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
-
- return send_netbios_packet( packet );
-}
-
-/***************************************************************************
- Sends out a name register.
-**************************************************************************/
-
-static BOOL initiate_name_register_packet( struct packet_struct *packet,
- uint16 nb_flags, struct in_addr *register_ip)
-{
- struct nmb_packet *nmb = &packet->packet.nmb;
-
- nmb->header.opcode = NMB_NAME_REG_OPCODE;
- nmb->header.arcount = 1;
-
- nmb->header.nm_flags.recursion_desired = True;
-
- if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
- return False;
-
- DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
-
- return send_netbios_packet( packet );
-}
-
-/***************************************************************************
- Sends out a multihomed name register.
-**************************************************************************/
-
-static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
- uint16 nb_flags, struct in_addr *register_ip)
-{
- struct nmb_packet *nmb = &packet->packet.nmb;
- fstring second_ip_buf;
-
- fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
-
- nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
- nmb->header.arcount = 1;
-
- nmb->header.nm_flags.recursion_desired = True;
-
- if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
- return False;
-
- DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
-for name %s IP %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
- BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
-
- return send_netbios_packet( packet );
-}
-
-/***************************************************************************
- Sends out a name refresh.
-**************************************************************************/
-
-static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
- uint16 nb_flags, struct in_addr *refresh_ip)
-{
- struct nmb_packet *nmb = &packet->packet.nmb;
-
- nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
- nmb->header.arcount = 1;
-
- nmb->header.nm_flags.recursion_desired = False;
-
- if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
- return False;
-
- DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
-
- return send_netbios_packet( packet );
-}
-
-/***************************************************************************
- Sends out a name release.
-**************************************************************************/
-
-static BOOL initiate_name_release_packet( struct packet_struct *packet,
- uint16 nb_flags, struct in_addr *release_ip)
-{
- struct nmb_packet *nmb = &packet->packet.nmb;
-
- nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
- nmb->header.arcount = 1;
-
- nmb->header.nm_flags.recursion_desired = False;
-
- if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
- return False;
-
- DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
-
- return send_netbios_packet( packet );
-}
-
-/***************************************************************************
- Sends out a node status.
-**************************************************************************/
-
-static BOOL initiate_node_status_packet( struct packet_struct *packet )
-{
- struct nmb_packet *nmb = &packet->packet.nmb;
-
- nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
- nmb->header.arcount = 0;
-
- nmb->header.nm_flags.recursion_desired = False;
-
- nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
-
- DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- inet_ntoa(packet->ip)));
-
- return send_netbios_packet( packet );
-}
-
-/****************************************************************************
- Simplification functions for queuing standard packets.
- These should be the only publicly callable functions for sending
- out packets.
-****************************************************************************/
-
-/****************************************************************************
- Assertion - we should never be sending nmbd packets on the remote
- broadcast subnet.
-****************************************************************************/
-
-static BOOL assert_check_subnet(struct subnet_record *subrec)
-{
- if( subrec == remote_broadcast_subnet)
- {
- DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
-This is a bug.\n"));
- return True;
- }
- return False;
-}
-
-/****************************************************************************
- Queue a register name packet to the broadcast address of a subnet.
-****************************************************************************/
-
-struct response_record *queue_register_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- uint16 nb_flags)
-{
- struct packet_struct *p;
- struct response_record *rrec;
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- /* note that all name registration requests have RD set (rfc1002 -
- section 4.2.2 */
- if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
- subrec->bcast_ip)) == NULL)
- return NULL;
-
- if(initiate_name_register_packet( p, nb_flags,
- iface_ip(subrec->bcast_ip)) == False)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
-}
-
-
-/****************************************************************************
- Queue a refresh name packet to the broadcast address of a subnet.
-****************************************************************************/
-void queue_wins_refresh(struct nmb_name *nmbname,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- uint16 nb_flags,
- struct in_addr refresh_ip,
- const char *tag)
-{
- struct packet_struct *p;
- struct response_record *rrec;
- struct in_addr wins_ip;
- struct userdata_struct *userdata;
- fstring ip_str;
-
- wins_ip = wins_srv_ip_tag(tag, refresh_ip);
-
- if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
- return;
- }
-
- if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
- p->locked = False;
- free_packet(p);
- return;
- }
-
- fstrcpy(ip_str, inet_ntoa(refresh_ip));
-
- DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
- nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
-
- userdata = (struct userdata_struct *)malloc(sizeof(*userdata) + strlen(tag) + 1);
- if (!userdata) {
- DEBUG(0,("Failed to allocate userdata structure!\n"));
- return;
- }
- ZERO_STRUCTP(userdata);
- userdata->userdata_len = strlen(tag) + 1;
- strlcpy(userdata->data, tag, userdata->userdata_len);
-
- if ((rrec = make_response_record(unicast_subnet,
- p,
- resp_fn, timeout_fn,
- NULL,
- NULL,
- userdata)) == NULL) {
- p->locked = False;
- free_packet(p);
- return;
- }
-
- free(userdata);
-
- /* we don't want to repeat refresh packets */
- rrec->repeat_count = 0;
-}
-
-
-/****************************************************************************
- Queue a multihomed register name packet to a given WINS server IP
-****************************************************************************/
-
-struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- uint16 nb_flags,
- struct in_addr register_ip,
- struct in_addr wins_ip)
-{
- struct packet_struct *p;
- struct response_record *rrec;
- BOOL ret;
-
- /* Sanity check. */
- if(subrec != unicast_subnet) {
- DEBUG(0,("queue_register_multihomed_name: should only be done on \
-unicast subnet. subnet is %s\n.", subrec->subnet_name ));
- return NULL;
- }
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
- return NULL;
-
- if (nb_flags & NB_GROUP)
- ret = initiate_name_register_packet( p, nb_flags, &register_ip);
- else
- ret = initiate_multihomed_name_register_packet(p, nb_flags, &register_ip);
-
- if (ret == False) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if ((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
-}
-
-/****************************************************************************
- Queue a release name packet to the broadcast address of a subnet.
-****************************************************************************/
-
-struct response_record *queue_release_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- release_name_success_function success_fn,
- release_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- uint16 nb_flags,
- struct in_addr release_ip,
- struct in_addr dest_ip)
-{
- struct packet_struct *p;
- struct response_record *rrec;
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False,
- dest_ip)) == NULL)
- return NULL;
-
- if(initiate_name_release_packet( p, nb_flags, &release_ip) == False)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- /*
- * For a broadcast release packet, only send once.
- * This will cause us to remove the name asap. JRA.
- */
-
- if (subrec != unicast_subnet) {
- rrec->repeat_count = 0;
- rrec->repeat_time = 0;
- }
-
- return rrec;
-}
-
-/****************************************************************************
- Queue a query name packet to the broadcast address of a subnet.
-****************************************************************************/
-
-struct response_record *queue_query_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- query_name_success_function success_fn,
- query_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname)
-{
- struct packet_struct *p;
- struct response_record *rrec;
- struct in_addr to_ip;
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- to_ip = subrec->bcast_ip;
-
- /* queries to the WINS server turn up here as queries to IP 0.0.0.0
- These need to be handled a bit differently */
- if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
- /* what we really need to do is loop over each of our wins
- * servers and wins server tags here, but that just doesn't
- * fit our architecture at the moment (userdata may already
- * be used when we get here). For now we just query the first
- * active wins server on the first tag. */
- char **tags = wins_srv_tags();
- if (!tags) {
- return NULL;
- }
- to_ip = wins_srv_ip_tag(tags[0], to_ip);
- wins_srv_tags_free(tags);
- }
-
- if(( p = create_and_init_netbios_packet(nmbname,
- (subrec != unicast_subnet),
- (subrec == unicast_subnet),
- to_ip)) == NULL)
- return NULL;
-
- if(lp_bind_interfaces_only()) {
- int i;
-
- DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
- for(i = 0; i < iface_count(); i++) {
- struct in_addr *ifip = iface_n_ip(i);
-
- if(ifip == NULL) {
- DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
- continue;
- }
-
- if (ip_equal(*ifip,loopback_ip)) {
- DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
- continue;
- }
-
- DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
- p->fd = find_subnet_fd_for_address( *ifip );
- break;
- }
- }
-
- if(initiate_name_query_packet( p ) == False) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
-}
-
-/****************************************************************************
- Queue a query name packet to a given address from the WINS subnet.
-****************************************************************************/
-
-struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- query_name_success_function success_fn,
- query_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname)
-{
- struct packet_struct *p;
- struct response_record *rrec;
-
- if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
- return NULL;
-
- if(initiate_name_query_packet_from_wins_server( p ) == False)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
-}
-
-/****************************************************************************
- Queue a node status packet to a given name and address.
-****************************************************************************/
-
-struct response_record *queue_node_status( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- node_status_success_function success_fn,
- node_status_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- struct in_addr send_ip)
-{
- struct packet_struct *p;
- struct response_record *rrec;
-
- /* Sanity check. */
- if(subrec != unicast_subnet)
- {
- DEBUG(0,("queue_register_multihomed_name: should only be done on \
-unicast subnet. subnet is %s\n.", subrec->subnet_name ));
- return NULL;
- }
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- if(( p = create_and_init_netbios_packet(nmbname, False, False,
- send_ip)) == NULL)
- return NULL;
-
- if(initiate_node_status_packet(p) == False)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
-}
-
-/****************************************************************************
- Reply to a netbios name packet. see rfc1002.txt
-****************************************************************************/
-
-void reply_netbios_packet(struct packet_struct *orig_packet,
- int rcode, enum netbios_reply_type_code rcv_code, int opcode,
- int ttl, char *data,int len)
-{
- struct packet_struct packet;
- struct nmb_packet *nmb = NULL;
- struct res_rec answers;
- struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
- BOOL loopback_this_packet = False;
- const char *packet_type = "unknown";
-
- /* Check if we are sending to or from ourselves. */
- if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
- loopback_this_packet = True;
-
- nmb = &packet.packet.nmb;
-
- /* Do a partial copy of the packet. We clear the locked flag and
- the resource record pointers. */
- packet = *orig_packet; /* Full structure copy. */
- packet.locked = False;
- nmb->answers = NULL;
- nmb->nsrecs = NULL;
- nmb->additional = NULL;
-
- switch (rcv_code)
- {
- case NMB_STATUS:
- {
- packet_type = "nmb_status";
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.recursion_available = False;
- break;
- }
- case NMB_QUERY:
- {
- packet_type = "nmb_query";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- }
- case NMB_REG:
- case NMB_REG_REFRESH:
- {
- packet_type = "nmb_reg";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- }
- case NMB_REL:
- {
- packet_type = "nmb_rel";
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.recursion_available = False;
- break;
- }
- case NMB_WAIT_ACK:
- {
- packet_type = "nmb_wack";
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.recursion_available = False;
- break;
- }
- case WINS_REG:
- {
- packet_type = "wins_reg";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- }
- case WINS_QUERY:
- {
- packet_type = "wins_query";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- }
-
- default:
- {
- DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
- packet_type, nmb_namestr(&orig_nmb->question.question_name),
- inet_ntoa(packet.ip)));
-
- return;
- }
- }
-
- DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
-for id %hu\n",
- packet_type, nmb_namestr(&orig_nmb->question.question_name),
- inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
-
- nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
- nmb->header.opcode = opcode;
- nmb->header.response = True;
- nmb->header.nm_flags.bcast = False;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = True;
-
- nmb->header.rcode = rcode;
- nmb->header.qdcount = 0;
- nmb->header.ancount = 1;
- nmb->header.nscount = 0;
- nmb->header.arcount = 0;
-
- memset((char*)&nmb->question,'\0',sizeof(nmb->question));
-
- nmb->answers = &answers;
- memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
-
- nmb->answers->rr_name = orig_nmb->question.question_name;
- nmb->answers->rr_type = orig_nmb->question.question_type;
- nmb->answers->rr_class = orig_nmb->question.question_class;
- nmb->answers->ttl = ttl;
-
- if (data && len)
- {
- nmb->answers->rdlength = len;
- memcpy(nmb->answers->rdata, data, len);
- }
-
- packet.packet_type = NMB_PACKET;
- /* Ensure we send out on the same fd that the original
- packet came in on to give the correct source IP address. */
- packet.fd = orig_packet->fd;
- packet.timestamp = time(NULL);
-
- debug_nmb_packet(&packet);
-
- if(loopback_this_packet)
- {
- struct packet_struct *lo_packet;
- DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
- if((lo_packet = copy_packet(&packet)) == NULL)
- return;
- queue_packet(lo_packet);
- }
- else if (!send_packet(&packet))
- {
- DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
- inet_ntoa(packet.ip),packet.port));
- }
-}
-
-/*******************************************************************
- Queue a packet into a packet queue
-******************************************************************/
-static void queue_packet(struct packet_struct *packet)
-{
- struct packet_struct *p;
-
- if (!packet_queue)
- {
- packet->prev = NULL;
- packet->next = NULL;
- packet_queue = packet;
- return;
- }
-
- /* find the bottom */
- for (p=packet_queue;p->next;p=p->next)
- ;
-
- p->next = packet;
- packet->next = NULL;
- packet->prev = p;
-}
-
-/****************************************************************************
- Try and find a matching subnet record for a datagram port 138 packet.
-****************************************************************************/
-
-static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
-{
- struct subnet_record *subrec;
-
- /* Go through all the broadcast subnets and see if the mask matches. */
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
- return subrec;
- }
-
- /* If the subnet record is the remote announce broadcast subnet,
- hack it here to be the first subnet. This is really gross and
- is needed due to people turning on port 137/138 broadcast
- forwarding on their routers. May fire and brimstone rain
- down upon them...
- */
-
- return FIRST_SUBNET;
-}
-
-/****************************************************************************
-Dispatch a browse frame from port 138 to the correct processing function.
-****************************************************************************/
-static void process_browse_packet(struct packet_struct *p, char *buf,int len)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- int command = CVAL(buf,0);
- struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
-
- /* Drop the packet if it's a different NetBIOS scope, or
- the source is from one of our names. */
-
- if (!strequal(dgram->dest_name.scope, lp_netbios_scope()))
- {
- DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
-mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, lp_netbios_scope()));
- return;
- }
-
- if (is_myname(dgram->source_name.name))
- {
- DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
-%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
- return;
- }
-
- switch (command)
- {
- case ANN_HostAnnouncement:
- {
- debug_browse_data(buf, len);
- process_host_announce(subrec, p, buf+1);
- break;
- }
- case ANN_DomainAnnouncement:
- {
- debug_browse_data(buf, len);
- process_workgroup_announce(subrec, p, buf+1);
- break;
- }
- case ANN_LocalMasterAnnouncement:
- {
- debug_browse_data(buf, len);
- process_local_master_announce(subrec, p, buf+1);
- break;
- }
- case ANN_AnnouncementRequest:
- {
- debug_browse_data(buf, len);
- process_announce_request(subrec, p, buf+1);
- break;
- }
- case ANN_Election:
- {
- debug_browse_data(buf, len);
- process_election(subrec, p, buf+1);
- break;
- }
- case ANN_GetBackupListReq:
- {
- debug_browse_data(buf, len);
- process_get_backup_list_request(subrec, p, buf+1);
- break;
- }
- case ANN_GetBackupListResp:
- {
- debug_browse_data(buf, len);
- /* We never send ANN_GetBackupListReq so we
- should never get these. */
- DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
-packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
- break;
- }
- case ANN_ResetBrowserState:
- {
- debug_browse_data(buf, len);
- process_reset_browser(subrec, p, buf+1);
- break;
- }
- case ANN_MasterAnnouncement:
- {
- /* Master browser datagrams must be processed
- on the unicast subnet. */
- subrec = unicast_subnet;
-
- debug_browse_data(buf, len);
- process_master_browser_announce(subrec, p, buf+1);
- break;
- }
- case ANN_BecomeBackup:
- {
- /*
- * We don't currently implement this. Log it just in case.
- */
- debug_browse_data(buf, len);
- DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
-command ANN_BecomeBackup from %s IP %s to %s\n",
- subrec->subnet_name, nmb_namestr(&dgram->source_name),
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- break;
- }
- default:
- {
- debug_browse_data(buf, len);
- DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
-command code %d from %s IP %s to %s\n",
- subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- }
- }
-}
-
-/****************************************************************************
- Dispatch a LanMan browse frame from port 138 to the correct processing function.
-****************************************************************************/
-static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- int command = SVAL(buf,0);
- struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
-
- /* Drop the packet if it's a different NetBIOS scope, or
- the source is from one of our names. */
-
- if (!strequal(dgram->dest_name.scope, lp_netbios_scope()))
- {
- DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
-mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, lp_netbios_scope()));
- return;
- }
-
- if (is_myname(dgram->source_name.name))
- {
- DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
-%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
- return;
- }
-
- switch (command)
- {
- case ANN_HostAnnouncement:
- {
- debug_browse_data(buf, len);
- process_lm_host_announce(subrec, p, buf+1);
- break;
- }
- case ANN_AnnouncementRequest:
- {
- process_lm_announce_request(subrec, p, buf+1);
- break;
- }
- default:
- {
- DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
-command code %d from %s IP %s to %s\n",
- subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- }
- }
-}
-
-/****************************************************************************
- Determine if a packet is for us on port 138. Note that to have any chance of
- being efficient we need to drop as many packets as possible at this
- stage as subsequent processing is expensive.
-****************************************************************************/
-
-static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
-{
- struct subnet_record *subrec = NULL;
-
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
- break;
- }
-
- if(subrec == NULL)
- subrec = unicast_subnet;
-
- return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
-}
-
-/****************************************************************************
- Process udp 138 datagrams
-****************************************************************************/
-static void process_dgram(struct packet_struct *p)
-{
- char *buf;
- char *buf2;
- int len;
- struct dgram_packet *dgram = &p->packet.dgram;
-
- /* If we aren't listening to the destination name then ignore the packet */
- if (!listening(p,&dgram->dest_name))
- {
- unexpected_packet(p);
- DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
- nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
- return;
- }
-
- if (dgram->header.msg_type != 0x10 &&
- dgram->header.msg_type != 0x11 &&
- dgram->header.msg_type != 0x12)
- {
- unexpected_packet(p);
- /* Don't process error packets etc yet */
- DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
-an error packet of type %x\n",
- nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
- return;
- }
-
- buf = &dgram->data[0];
- buf -= 4; /* XXXX for the pseudo tcp length -
- someday I need to get rid of this */
-
- if (CVAL(buf,smb_com) != SMBtrans)
- return;
-
- len = SVAL(buf,smb_vwv11);
- buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
-
- if (len <= 0)
- return;
-
- if (buf2 + len > buf + sizeof(dgram->data)) {
- DEBUG(2,("process_dgram: datagram from %s to %s IP %s for %s len=%d too long.\n",
- nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
- inet_ntoa(p->ip), smb_buf(buf),len));
- len = (buf + sizeof(dgram->data)) - buf;
- }
-
- DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
- nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
- inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
-
-
- /* Datagram packet received for the browser mailslot */
- if (strequal(smb_buf(buf),BROWSE_MAILSLOT))
- {
- process_browse_packet(p,buf2,len);
- return;
- }
-
- /* Datagram packet received for the LAN Manager mailslot */
- if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
- process_lanman_packet(p,buf2,len);
- return;
- }
-
- /* Datagram packet received for the domain logon mailslot */
- if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT))
- {
- process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
- return;
- }
-
- /* Datagram packet received for the NT domain logon mailslot */
- if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT))
- {
- process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
- return;
- }
-
- unexpected_packet(p);
-}
-
-/****************************************************************************
- Validate a response nmb packet.
-****************************************************************************/
-
-static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
-{
- BOOL ignore = False;
-
- switch (nmb->header.opcode)
- {
- case NMB_NAME_REG_OPCODE:
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
- if (nmb->header.ancount == 0)
- {
- DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_NAME_QUERY_OPCODE:
- if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1))
- {
- DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
- ignore = True;
- }
- break;
- case NMB_NAME_RELEASE_OPCODE:
- if (nmb->header.ancount == 0)
- {
- DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
- ignore = True;
- }
- break;
- case NMB_WACK_OPCODE:
- /* Check WACK response here. */
- if (nmb->header.ancount != 1)
- {
- DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
- ignore = True;
- }
- break;
- default:
- DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
- nmb->header.opcode));
- return True;
- }
-
- if(ignore)
- DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
-
- return ignore;
-}
-
-/****************************************************************************
- Validate a request nmb packet.
-****************************************************************************/
-
-static BOOL validate_nmb_packet( struct nmb_packet *nmb )
-{
- BOOL ignore = False;
-
- switch (nmb->header.opcode)
- {
- case NMB_NAME_REG_OPCODE:
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- if (nmb->header.qdcount==0 || nmb->header.arcount==0)
- {
- DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_NAME_QUERY_OPCODE:
- if ((nmb->header.qdcount == 0) ||
- ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
- (nmb->question.question_type != QUESTION_TYPE_NB_STATUS)))
- {
- DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_NAME_RELEASE_OPCODE:
- if (nmb->header.qdcount==0 || nmb->header.arcount==0)
- {
- DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
- ignore = True;
- }
- break;
- default:
- DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
- nmb->header.opcode));
- return True;
- }
-
- if(ignore)
- DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
-
- return ignore;
-}
-
-/****************************************************************************
- Find a subnet (and potentially a response record) for a packet.
-****************************************************************************/
-
-static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
- struct response_record **pprrec)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct response_record *rrec = NULL;
- struct subnet_record *subrec = NULL;
-
- if(pprrec != NULL)
- *pprrec = NULL;
-
- if(nmb->header.response)
- {
- /* It's a response packet. Find a record for it or it's an error. */
-
- rrec = find_response_record( &subrec, nmb->header.name_trn_id);
- if(rrec == NULL)
- {
- DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
- nmb->header.name_trn_id));
- unexpected_packet(p);
- return NULL;
- }
-
- if(subrec == NULL)
- {
- DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
- nmb->header.name_trn_id));
- return NULL;
- }
-
- if(pprrec != NULL)
- *pprrec = rrec;
- return subrec;
- }
-
- /* Try and see what subnet this packet belongs to. */
-
- /* WINS server ? */
- if(packet_is_for_wins_server(p))
- return wins_server_subnet;
-
- /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
- if(nmb->header.nm_flags.bcast == False)
- return unicast_subnet;
-
- /* Go through all the broadcast subnets and see if the mask matches. */
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
- return subrec;
- }
-
- /* If none match it must have been a directed broadcast - assign
- the remote_broadcast_subnet. */
- return remote_broadcast_subnet;
-}
-
-/****************************************************************************
- Process a nmb request packet - validate the packet and route it.
-****************************************************************************/
-
-static void process_nmb_request(struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct subnet_record *subrec = NULL;
-
- debug_nmb_packet(p);
-
- /* Ensure we have a good packet. */
- if(validate_nmb_packet(nmb))
- return;
-
- /* Allocate a subnet to this packet - if we cannot - fail. */
- if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
- return;
-
- switch (nmb->header.opcode)
- {
- case NMB_NAME_REG_OPCODE:
- if(subrec == wins_server_subnet)
- wins_process_name_registration_request(subrec, p);
- else
- process_name_registration_request(subrec, p);
- break;
-
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9:
- if(subrec == wins_server_subnet)
- wins_process_name_refresh_request(subrec, p);
- else
- process_name_refresh_request(subrec, p);
- break;
-
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- if(subrec == wins_server_subnet)
- wins_process_multihomed_name_registration_request(subrec, p);
- else
- {
- DEBUG(0,("process_nmb_request: Multihomed registration request must be \
-directed at a WINS server.\n"));
- }
- break;
-
- case NMB_NAME_QUERY_OPCODE:
- switch (nmb->question.question_type)
- {
- case QUESTION_TYPE_NB_QUERY:
- {
- if(subrec == wins_server_subnet)
- wins_process_name_query_request(subrec, p);
- else
- process_name_query_request(subrec, p);
- break;
- }
- case QUESTION_TYPE_NB_STATUS:
- {
- if(subrec == wins_server_subnet)
- {
- DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
-not allowed.\n"));
- break;
- }
- else
- process_node_status_request(subrec, p);
- break;
- }
- }
- break;
-
- case NMB_NAME_RELEASE_OPCODE:
- if(subrec == wins_server_subnet)
- wins_process_name_release_request(subrec, p);
- else
- process_name_release_request(subrec, p);
- break;
- }
-}
-
-/****************************************************************************
- Process a nmb response packet - validate the packet and route it.
- to either the WINS server or a normal response.
-****************************************************************************/
-
-static void process_nmb_response(struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct subnet_record *subrec = NULL;
- struct response_record *rrec = NULL;
-
- debug_nmb_packet(p);
-
- if(validate_nmb_response_packet(nmb))
- return;
-
- if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
- return;
-
- if(rrec == NULL)
- {
- DEBUG(0,("process_nmb_response: response packet received but no response record \
-found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
- return;
- }
-
- /* Increment the number of responses received for this record. */
- rrec->num_msgs++;
- /* Ensure we don't re-send the request. */
- rrec->repeat_count = 0;
-
- /* Call the response received function for this packet. */
- (*rrec->resp_fn)(subrec, rrec, p);
-}
-
-
-/*******************************************************************
- Run elements off the packet queue till its empty
-******************************************************************/
-
-void run_packet_queue(void)
-{
- struct packet_struct *p;
-
- while ((p = packet_queue))
- {
- packet_queue = p->next;
- if (packet_queue)
- packet_queue->prev = NULL;
- p->next = p->prev = NULL;
-
- switch (p->packet_type)
- {
- case NMB_PACKET:
- if(p->packet.nmb.header.response)
- process_nmb_response(p);
- else
- process_nmb_request(p);
- break;
-
- case DGRAM_PACKET:
- process_dgram(p);
- break;
- }
- free_packet(p);
- }
-}
-
-/*******************************************************************
- Retransmit or timeout elements from all the outgoing subnet response
- record queues. NOTE that this code must also check the WINS server
- subnet for response records to timeout as the WINS server code
- can send requests to check if a client still owns a name.
- (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
-******************************************************************/
-
-void retransmit_or_expire_response_records(time_t t)
-{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec;
- subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec))
- {
- struct response_record *rrec, *nextrrec;
-
- for (rrec = subrec->responselist; rrec; rrec = nextrrec)
- {
- nextrrec = rrec->next;
-
- if (rrec->repeat_time <= t)
- {
- if (rrec->repeat_count > 0)
- {
- /* Resend while we have a non-zero repeat_count. */
- if(!send_packet(rrec->packet))
- {
- DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
-to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
- subrec->subnet_name));
- }
- rrec->repeat_time = t + rrec->repeat_interval;
- rrec->repeat_count--;
- }
- else
- {
- DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
-on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
- subrec->subnet_name));
-
- /*
- * Check the flag in this record to prevent recursion if we end
- * up in this function again via the timeout function call.
- */
-
- if(!rrec->in_expiration_processing)
- {
-
- /*
- * Set the recursion protection flag in this record.
- */
-
- rrec->in_expiration_processing = True;
-
- /* Call the timeout function. This will deal with removing the
- timed out packet. */
- if(rrec->timeout_fn)
- (*rrec->timeout_fn)(subrec, rrec);
- else
- {
- /* We must remove the record ourself if there is
- no timeout function. */
- remove_response_record(subrec, rrec);
- }
- } /* !rrec->in_expitation_processing */
- } /* rrec->repeat_count > 0 */
- } /* rrec->repeat_time <= t */
- } /* end for rrec */
- } /* end for subnet */
-}
-
-/****************************************************************************
- Create an fd_set containing all the sockets in the subnet structures,
- plus the broadcast sockets.
-***************************************************************************/
-
-static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number)
-{
- int *sock_array = NULL;
- struct subnet_record *subrec = NULL;
- int count = 0;
- int num = 0;
- fd_set *pset = (fd_set *)malloc(sizeof(fd_set));
-
- if(pset == NULL)
- {
- DEBUG(0,("create_listen_fdset: malloc fail !\n"));
- return True;
- }
-
- /* Check that we can add all the fd's we need. */
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- count++;
-
- if((count*2) + 2 > FD_SETSIZE)
- {
- DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
-only use %d.\n", (count*2) + 2, FD_SETSIZE));
- return True;
- }
-
- if((sock_array = (int *)malloc(((count*2) + 2)*sizeof(int))) == NULL)
- {
- DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
- return True;
- }
-
- FD_ZERO(pset);
-
- /* Add in the broadcast socket on 137. */
- FD_SET(ClientNMB,pset);
- sock_array[num++] = ClientNMB;
-
- /* Add in the 137 sockets on all the interfaces. */
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- FD_SET(subrec->nmb_sock,pset);
- sock_array[num++] = subrec->nmb_sock;
- }
-
- /* Add in the broadcast socket on 138. */
- FD_SET(ClientDGRAM,pset);
- sock_array[num++] = ClientDGRAM;
-
- /* Add in the 138 sockets on all the interfaces. */
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- FD_SET(subrec->dgram_sock,pset);
- sock_array[num++] = subrec->dgram_sock;
- }
-
- *listen_number = (count*2) + 2;
-
- SAFE_FREE(*ppset);
- SAFE_FREE(*psock_array);
-
- *ppset = pset;
- *psock_array = sock_array;
-
- return False;
-}
-
-/****************************************************************************
- Listens for NMB or DGRAM packets, and queues them.
- return True if the socket is dead
-***************************************************************************/
-
-BOOL listen_for_packets(BOOL run_election)
-{
- static fd_set *listen_set = NULL;
- static int listen_number = 0;
- static int *sock_array = NULL;
- int i;
-
- fd_set fds;
- int selrtn;
- struct timeval timeout;
-#ifndef SYNC_DNS
- int dns_fd;
-#endif
-
- if(listen_set == NULL || rescan_listen_set)
- {
- if(create_listen_fdset(&listen_set, &sock_array, &listen_number))
- {
- DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
- return True;
- }
- rescan_listen_set = False;
- }
-
- memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
-
-#ifndef SYNC_DNS
- dns_fd = asyncdns_fd();
- if (dns_fd != -1) {
- FD_SET(dns_fd, &fds);
- }
-#endif
-
-
- /*
- * During elections and when expecting a netbios response packet we
- * need to send election packets at tighter intervals.
- * Ideally it needs to be the interval (in ms) between time now and
- * the time we are expecting the next netbios packet.
- */
-
- timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
- timeout.tv_usec = 0;
-
- /* Prepare for the select - allow certain signals. */
-
- BlockSignals(False, SIGTERM);
-
- selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
-
- /* We can only take signals when we are in the select - block them again here. */
-
- BlockSignals(True, SIGTERM);
-
- if(selrtn == -1) {
- return False;
- }
-
-#ifndef SYNC_DNS
- if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
- run_dns_queue();
- }
-#endif
-
- for(i = 0; i < listen_number; i++) {
- if (i < (listen_number/2)) {
- /* Processing a 137 socket. */
- if (FD_ISSET(sock_array[i],&fds)) {
- struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
- if (packet) {
- /*
- * If we got a packet on the broadcast socket and interfaces
- * only is set then check it came from one of our local nets.
- */
- if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
- (!is_local_net(packet->ip))) {
- DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else if ((ip_equal(loopback_ip, packet->ip) ||
- ismyip(packet->ip)) && packet->port == global_nmb_port &&
- packet->packet.nmb.header.nm_flags.bcast) {
- DEBUG(7,("discarding own bcast packet from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else {
- /* Save the file descriptor this packet came in on. */
- packet->fd = sock_array[i];
- queue_packet(packet);
- }
- }
- }
- } else {
- /* Processing a 138 socket. */
- if (FD_ISSET(sock_array[i],&fds)) {
- struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
- if (packet) {
- /*
- * If we got a packet on the broadcast socket and interfaces
- * only is set then check it came from one of our local nets.
- */
- if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
- (!is_local_net(packet->ip))) {
- DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else if ((ip_equal(loopback_ip, packet->ip) ||
- ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
- DEBUG(7,("discarding own dgram packet from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else {
- /* Save the file descriptor this packet came in on. */
- packet->fd = sock_array[i];
- queue_packet(packet);
- }
- }
- }
- } /* end processing 138 socket. */
- } /* end for */
- return False;
-}
-
-/****************************************************************************
- Construct and send a netbios DGRAM.
-**************************************************************************/
-BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf,int len,
- const char *srcname, int src_type,
- const char *dstname, int dest_type,
- struct in_addr dest_ip,struct in_addr src_ip,
- int dest_port)
-{
- BOOL loopback_this_packet = False;
- struct packet_struct p;
- struct dgram_packet *dgram = &p.packet.dgram;
- char *ptr,*p2;
- char tmp[4];
-
- memset((char *)&p,'\0',sizeof(p));
-
- if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
- loopback_this_packet = True;
-
- /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
-
- /* DIRECT GROUP or UNIQUE datagram. */
- dgram->header.msg_type = unique ? 0x10 : 0x11;
- dgram->header.flags.node_type = M_NODE;
- dgram->header.flags.first = True;
- dgram->header.flags.more = False;
- dgram->header.dgm_id = generate_name_trn_id();
- dgram->header.source_ip = src_ip;
- dgram->header.source_port = DGRAM_PORT;
- dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
- dgram->header.packet_offset = 0;
-
- make_nmb_name(&dgram->source_name,srcname,src_type);
- make_nmb_name(&dgram->dest_name,dstname,dest_type);
-
- ptr = &dgram->data[0];
-
- /* Setup the smb part. */
- ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
- memcpy(tmp,ptr,4);
- set_message(ptr,17,23 + len,True);
- memcpy(ptr,tmp,4);
-
- SCVAL(ptr,smb_com,SMBtrans);
- SSVAL(ptr,smb_vwv1,len);
- SSVAL(ptr,smb_vwv11,len);
- SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
- SSVAL(ptr,smb_vwv13,3);
- SSVAL(ptr,smb_vwv14,1);
- SSVAL(ptr,smb_vwv15,1);
- SSVAL(ptr,smb_vwv16,2);
- p2 = smb_buf(ptr);
- pstrcpy(p2,mailslot);
- p2 = skip_string(p2,1);
-
- memcpy(p2,buf,len);
- p2 += len;
-
- dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
-
- p.ip = dest_ip;
- p.port = dest_port;
- p.fd = find_subnet_mailslot_fd_for_address( src_ip );
- p.timestamp = time(NULL);
- p.packet_type = DGRAM_PACKET;
-
- DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
- nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
- DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
-
- debug_browse_data(buf, len);
-
- if(loopback_this_packet)
- {
- struct packet_struct *lo_packet = NULL;
- DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
- if((lo_packet = copy_packet(&p)) == NULL)
- return False;
- queue_packet(lo_packet);
- return True;
- }
- else
- return(send_packet(&p));
-}
diff --git a/source4/nmbd/nmbd_processlogon.c b/source4/nmbd/nmbd_processlogon.c
deleted file mode 100644
index 1fcfd11a3e..0000000000
--- a/source4/nmbd/nmbd_processlogon.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
- Copyright (C) Jim McDonough 2002
- Copyright (C) Anthony Liguori 2002
-
- 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.
-
- Revision History:
-
-*/
-
-#include "includes.h"
-
-struct sam_database_info {
- uint32 index;
- uint32 serial_lo, serial_hi;
- uint32 date_lo, date_hi;
-};
-
-/****************************************************************************
-Send a message to smbd to do a sam delta sync
-**************************************************************************/
-static void send_repl_message(uint32 low_serial)
-{
- TDB_CONTEXT *tdb;
-
- tdb = tdb_open_log(lock_path("connections.tdb"), 0,
- TDB_DEFAULT, O_RDONLY, 0);
-
- if (!tdb) {
- DEBUG(3, ("send_repl_message(): failed to open connections "
- "database\n"));
- return;
- }
-
- DEBUG(3, ("sending replication message, serial = 0x%04x\n",
- low_serial));
-
- message_send_all(tdb, MSG_SMB_SAM_REPL, &low_serial,
- sizeof(low_serial), False, NULL);
-
- tdb_close(tdb);
-}
-
-/****************************************************************************
-Process a domain logon packet
-**************************************************************************/
-
-void process_logon_packet(struct packet_struct *p, char *buf,int len,
- const char *mailslot)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- pstring my_name;
- fstring reply_name;
- pstring outbuf;
- int code;
- uint16 token = 0;
- uint32 ntversion = 0;
- uint16 lmnttoken = 0;
- uint16 lm20token = 0;
- uint32 domainsidsize;
- BOOL short_request = False;
- char *getdc;
- char *uniuser; /* Unicode user name. */
- pstring ascuser;
- char *unicomp; /* Unicode computer name. */
-
- memset(outbuf, 0, sizeof(outbuf));
-
- if (!lp_domain_logons())
- {
- DEBUG(3,("process_logon_packet: Logon packet received from IP %s and domain \
-logons are not enabled.\n", inet_ntoa(p->ip) ));
- return;
- }
-
- pstrcpy(my_name, lp_netbios_name());
-
- code = SVAL(buf,0);
- DEBUG(1,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code));
-
- switch (code)
- {
- case 0:
- {
- char *q = buf + 2;
- char *machine = q;
- char *user = skip_string(machine,1);
-
- getdc = skip_string(user,1);
- q = skip_string(getdc,1);
- token = SVAL(q,3);
-
- fstrcpy(reply_name,my_name);
-
- DEBUG(3,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
- machine,inet_ntoa(p->ip),user,token));
-
- q = outbuf;
- SSVAL(q, 0, 6);
- q += 2;
-
- fstrcpy(reply_name, "\\\\");
- fstrcat(reply_name, my_name);
- fstrcpy(q, reply_name); q = skip_string(q, 1); /* PDC name */
-
- SSVAL(q, 0, token);
- q += 2;
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- lp_netbios_name(), 0x0,
- machine,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- break;
- }
-
- case QUERYFORPDC:
- {
- char *q = buf + 2;
- char *machine = q;
-
- if (!lp_domain_master())
- {
- /* We're not Primary Domain Controller -- ignore this */
- return;
- }
-
- getdc = skip_string(machine,1);
- q = skip_string(getdc,1);
- q = ALIGN2(q, buf);
-
- /* at this point we can work out if this is a W9X or NT style
- request. Experiments show that the difference is wether the
- packet ends here. For a W9X request we now end with a pair of
- bytes (usually 0xFE 0xFF) whereas with NT we have two further
- strings - the following is a simple way of detecting this */
- if (len - PTR_DIFF(q, buf) <= 3) {
- short_request = True;
- } else {
- unicomp = q;
-
- /* A full length (NT style) request */
- q = skip_unibuf(unicomp, PTR_DIFF(buf + len, unicomp));
-
- if (len - PTR_DIFF(q, buf) > 8) {
- /* with NT5 clients we can sometimes
- get additional data - a length specificed string
- containing the domain name, then 16 bytes of
- data (no idea what it is) */
- int dom_len = CVAL(q, 0);
- q++;
- if (dom_len != 0) {
- q += dom_len + 1;
- }
- q += 16;
- }
- ntversion = IVAL(q, 0);
- lmnttoken = SVAL(q, 4);
- lm20token = SVAL(q, 6);
- }
-
- /* Construct reply. */
- q = outbuf;
- SSVAL(q, 0, QUERYFORPDC_R);
- q += 2;
-
- fstrcpy(reply_name,my_name);
- fstrcpy(q, reply_name);
- q = skip_string(q, 1); /* PDC name */
-
- /* PDC and domain name */
- if (!short_request) /* Make a full reply */
- {
- q = ALIGN2(q, outbuf);
-
- q += dos_PutUniCode(q, my_name, sizeof(pstring), True); /* PDC name */
- q += dos_PutUniCode(q, lp_workgroup(),sizeof(pstring), True); /* Domain name*/
- SIVAL(q, 0, 1); /* our nt version */
- SSVAL(q, 4, 0xffff); /* our lmnttoken */
- SSVAL(q, 6, 0xffff); /* our lm20token */
- q += 8;
- }
-
- /* RJS, 21-Feb-2000, we send a short reply if the request was short */
-
- DEBUG(3,("process_logon_packet: GETDC request from %s at IP %s, \
-reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
- machine,inet_ntoa(p->ip), reply_name, lp_workgroup(),
- QUERYFORPDC_R, (uint32)ntversion, (uint32)lmnttoken,
- (uint32)lm20token ));
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- lp_netbios_name(), 0x0,
- dgram->source_name.name,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- return;
- }
-
- case SAMLOGON:
- {
- char *q = buf + 2;
- fstring asccomp;
-
- q += 2;
- unicomp = q;
- uniuser = skip_unibuf(unicomp, PTR_DIFF(buf+len, unicomp));
- getdc = skip_unibuf(uniuser,PTR_DIFF(buf+len, uniuser));
- q = skip_string(getdc,1);
- q += 4; /* Account Control Bits - indicating username type */
- domainsidsize = IVAL(q, 0);
- q += 4;
-
- DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d, len = %d\n", domainsidsize, len));
-
- if (domainsidsize < (len - PTR_DIFF(q, buf)) && (domainsidsize != 0)) {
- q += domainsidsize;
- q = ALIGN4(q, buf);
- }
-
- DEBUG(3,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %d\n", len, PTR_DIFF(q, buf) ));
-
- if (len - PTR_DIFF(q, buf) > 8) {
- /* with NT5 clients we can sometimes
- get additional data - a length specificed string
- containing the domain name, then 16 bytes of
- data (no idea what it is) */
- int dom_len = CVAL(q, 0);
- q++;
- if (dom_len < (len - PTR_DIFF(q, buf)) && (dom_len != 0)) {
- q += dom_len + 1;
- }
- q += 16;
- }
-
- ntversion = IVAL(q, 0);
- lmnttoken = SVAL(q, 4);
- lm20token = SVAL(q, 6);
- q += 8;
-
- DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %d\n", domainsidsize, ntversion));
-
- /*
- * we respond regadless of whether the machine is in our password
- * database. If it isn't then we let smbd send an appropriate error.
- * Let's ignore the SID.
- */
- pull_ucs2_pstring(ascuser, uniuser);
- pull_ucs2_fstring(asccomp, unicomp);
- DEBUG(3,("process_logon_packet: SAMLOGON user %s\n", ascuser));
-
- fstrcpy(reply_name, "\\\\"); /* Here it wants \\LOGONSERVER. */
- fstrcat(reply_name, my_name);
-
- DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
- asccomp,inet_ntoa(p->ip), ascuser, reply_name, lp_workgroup(),
- SAMLOGON_R ,lmnttoken));
-
- /* Construct reply. */
-
- q = outbuf;
- /* we want the simple version unless we are an ADS PDC..which means */
- /* never, at least for now */
- if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) {
- if (SVAL(uniuser, 0) == 0) {
- SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
- } else {
- SSVAL(q, 0, SAMLOGON_R);
- }
-
- q += 2;
-
- q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
- q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
- q += dos_PutUniCode(q, lp_workgroup(),sizeof(pstring), True);
- }
-#ifdef HAVE_ADS
- else {
- GUID domain_guid;
- pstring domain;
- char *hostname = NULL;
- char *component, *dc, *q1;
- uint8 size;
-
- get_mydomname(domain);
- hostname = get_myname();
-
- if (SVAL(uniuser, 0) == 0) {
- SSVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
- } else {
- SSVAL(q, 0, SAMLOGON_AD_R);
- }
- q += 2;
-
- SSVAL(q, 0, 0);
- q += 2;
- SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS|
- ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE);
- q += 4;
-
- /* Push Domain GUID */
- if (False == secrets_fetch_domain_guid(domain, &domain_guid)) {
- DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain));
- return;
- }
- memcpy(q, &domain_guid, sizeof(domain_guid));
- q += sizeof(domain_guid);
-
- /* Push domain components */
- dc = domain;
- q1 = q;
- while ((component = strtok(dc, "."))) {
- dc = NULL;
- size = push_ascii(&q[1], component, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- }
- SCVAL(q, 0, 0); q++;
- SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
- q += 2; /* it must follow the domain name. */
-
- /* Push dns host name */
- size = push_ascii(&q[1], hostname, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
- q += 2; /* it must follow the domain name. */
-
- /* Push NETBIOS of domain */
- size = push_ascii(&q[1], lp_workgroup(), -1, STR_UPPER);
- SCVAL(q, 0, size);
- q += (size + 1);
- SCVAL(q, 0, 0); q++; /* is this a null terminator or empty field */
- /* null terminator would not be needed because size is included */
-
- /* Push NETBIOS of hostname */
- size = push_ascii(&q[1], my_name, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- SCVAL(q, 0, 0); q++; /* null terminator or empty field? */
-
- /* Push user account */
- size = push_ascii(&q[1], ascuser, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
-
- /* Push 'Default-First-Site-Name' */
- size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
-
- SSVAL(q, 0, 0xc000); /* unknown */
- SCVAL(q, 2, PTR_DIFF(q,q1));
- SCVAL(q, 3, 0x10); /* unknown */
- q += 4;
-
- SIVAL(q, 0, 0x00000002); q += 4; /* unknown */
- SIVAL(q, 0, (iface_ip(p->ip))->s_addr); q += 4;
- SIVAL(q, 0, 0x00000000); q += 4; /* unknown */
- SIVAL(q, 0, 0x00000000); q += 4; /* unknown */
- if (hostname) free(hostname);
- }
-#endif
-
- /* tell the client what version we are */
- SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13);
- /* our ntversion */
- SSVAL(q, 4, 0xffff); /* our lmnttoken */
- SSVAL(q, 6, 0xffff); /* our lm20token */
- q += 8;
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- lp_netbios_name(), 0x0,
- dgram->source_name.name,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- break;
- }
-
- /* Announce change to UAS or SAM. Send by the domain controller when a
- replication event is required. */
-
- case SAM_UAS_CHANGE: {
- struct sam_database_info *db_info;
- char *q = buf + 2;
- int i, db_count;
- uint32 low_serial;
-
- /* Header */
-
- low_serial = IVAL(q, 0); q += 4; /* Low serial number */
-
- q += 4; /* Date/time */
- q += 4; /* Pulse */
- q += 4; /* Random */
-
- /* Domain info */
-
- q = skip_string(q, 1); /* PDC name */
- q = skip_string(q, 1); /* Domain name */
- q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode PDC name */
- q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode domain name */
-
- /* Database info */
-
- db_count = SVAL(q, 0); q += 2;
-
- db_info = (struct sam_database_info *)
- malloc(sizeof(struct sam_database_info) * db_count);
-
- if (db_info == NULL) {
- DEBUG(3, ("out of memory allocating info for %d databases\n",
- db_count));
- return;
- }
-
- for (i = 0; i < db_count; i++) {
- db_info[i].index = IVAL(q, 0);
- db_info[i].serial_lo = IVAL(q, 4);
- db_info[i].serial_hi = IVAL(q, 8);
- db_info[i].date_lo = IVAL(q, 12);
- db_info[i].date_hi = IVAL(q, 16);
- q += 20;
- }
-
- /* Domain SID */
-
- q += IVAL(q, 0) + 4; /* 4 byte length plus data */
-
- q += 2; /* Alignment? */
-
- /* Misc other info */
-
- q += 4; /* NT version (0x1) */
- q += 2; /* LMNT token (0xff) */
- q += 2; /* LM20 token (0xff) */
-
- SAFE_FREE(db_info); /* Not sure whether we need to do anything
- useful with these */
-
- /* Send message to smbd */
-
- send_repl_message(low_serial);
-
- break;
- }
-
- default:
- {
- DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code));
- return;
- }
- }
-}
diff --git a/source4/nmbd/nmbd_responserecordsdb.c b/source4/nmbd/nmbd_responserecordsdb.c
deleted file mode 100644
index 7e8c8025ae..0000000000
--- a/source4/nmbd/nmbd_responserecordsdb.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios library routines
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-extern int ClientNMB;
-
-int num_response_packets = 0;
-
-/***************************************************************************
- Add an expected response record into the list
- **************************************************************************/
-
-static void add_response_record(struct subnet_record *subrec,
- struct response_record *rrec)
-{
- struct response_record *rrec2;
-
- num_response_packets++; /* count of total number of packets still around */
-
- DEBUG(4,("add_response_record: adding response record id:%hu to subnet %s. num_records:%d\n",
- rrec->response_id, subrec->subnet_name, num_response_packets));
-
- if (!subrec->responselist)
- {
- subrec->responselist = rrec;
- rrec->prev = NULL;
- rrec->next = NULL;
- return;
- }
-
- for (rrec2 = subrec->responselist; rrec2->next; rrec2 = rrec2->next)
- ;
-
- rrec2->next = rrec;
- rrec->next = NULL;
- rrec->prev = rrec2;
-}
-
-/***************************************************************************
- Remove an expected response record from the list
- **************************************************************************/
-
-void remove_response_record(struct subnet_record *subrec,
- struct response_record *rrec)
-{
- if (rrec->prev)
- rrec->prev->next = rrec->next;
- if (rrec->next)
- rrec->next->prev = rrec->prev;
-
- if (subrec->responselist == rrec)
- subrec->responselist = rrec->next;
-
- if(rrec->userdata)
- {
- if(rrec->userdata->free_fn) {
- (*rrec->userdata->free_fn)(rrec->userdata);
- } else {
- ZERO_STRUCTP(rrec->userdata);
- SAFE_FREE(rrec->userdata);
- }
- }
-
- /* Ensure we can delete. */
- rrec->packet->locked = False;
- free_packet(rrec->packet);
-
- ZERO_STRUCTP(rrec);
- SAFE_FREE(rrec);
-
- num_response_packets--; /* count of total number of packets still around */
-}
-
-/****************************************************************************
- Create a response record for an outgoing packet.
- **************************************************************************/
-
-struct response_record *make_response_record( struct subnet_record *subrec,
- struct packet_struct *p,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- success_function success_fn,
- fail_function fail_fn,
- struct userdata_struct *userdata)
-{
- struct response_record *rrec;
- struct nmb_packet *nmb = &p->packet.nmb;
-
- if (!(rrec = (struct response_record *)malloc(sizeof(*rrec))))
- {
- DEBUG(0,("make_response_queue_record: malloc fail for response_record.\n"));
- return NULL;
- }
-
- memset((char *)rrec, '\0', sizeof(*rrec));
-
- rrec->response_id = nmb->header.name_trn_id;
-
- rrec->resp_fn = resp_fn;
- rrec->timeout_fn = timeout_fn;
- rrec->success_fn = success_fn;
- rrec->fail_fn = fail_fn;
-
- rrec->packet = p;
-
- if(userdata)
- {
- /* Intelligent userdata. */
- if(userdata->copy_fn)
- {
- if((rrec->userdata = (*userdata->copy_fn)(userdata)) == NULL)
- {
- DEBUG(0,("make_response_queue_record: copy fail for userdata.\n"));
- ZERO_STRUCTP(rrec);
- SAFE_FREE(rrec);
- return NULL;
- }
- }
- else
- {
- /* Primitive userdata, do a memcpy. */
- if((rrec->userdata = (struct userdata_struct *)
- malloc(sizeof(struct userdata_struct)+userdata->userdata_len)) == NULL)
- {
- DEBUG(0,("make_response_queue_record: malloc fail for userdata.\n"));
- ZERO_STRUCTP(rrec);
- SAFE_FREE(rrec);
- return NULL;
- }
- rrec->userdata->copy_fn = userdata->copy_fn;
- rrec->userdata->free_fn = userdata->free_fn;
- rrec->userdata->userdata_len = userdata->userdata_len;
- memcpy(rrec->userdata->data, userdata->data, userdata->userdata_len);
- }
- }
- else
- rrec->userdata = NULL;
-
- rrec->num_msgs = 0;
-
- if(!nmb->header.nm_flags.bcast)
- rrec->repeat_interval = 5; /* 5 seconds for unicast packets. */
- else
- rrec->repeat_interval = 1; /* XXXX should be in ms */
- rrec->repeat_count = 3; /* 3 retries */
- rrec->repeat_time = time(NULL) + rrec->repeat_interval; /* initial retry time */
-
- /* This packet is not being processed. */
- rrec->in_expiration_processing = False;
-
- /* Lock the packet so we won't lose it while it's on the list. */
- p->locked = True;
-
- add_response_record(subrec, rrec);
-
- return rrec;
-}
-
-/****************************************************************************
- Find a response in a subnet's name query response list.
- **************************************************************************/
-
-static struct response_record *find_response_record_on_subnet(
- struct subnet_record *subrec, uint16 id)
-{
- struct response_record *rrec = NULL;
-
- for (rrec = subrec->responselist; rrec; rrec = rrec->next)
- {
- if (rrec->response_id == id)
- {
- DEBUG(4, ("find_response_record: found response record id = %hu on subnet %s\n",
- id, subrec->subnet_name));
- break;
- }
- }
- return rrec;
-}
-
-/****************************************************************************
- Find a response in any subnet's name query response list.
- **************************************************************************/
-
-struct response_record *find_response_record(struct subnet_record **ppsubrec,
- uint16 id)
-{
- struct response_record *rrec = NULL;
-
- for ((*ppsubrec) = FIRST_SUBNET; (*ppsubrec);
- (*ppsubrec) = NEXT_SUBNET_INCLUDING_UNICAST(*ppsubrec))
- {
- if((rrec = find_response_record_on_subnet(*ppsubrec, id)) != NULL)
- return rrec;
- }
-
- /* There should never be response records on the remote_broadcast subnet.
- Sanity check to ensure this is so. */
- if(remote_broadcast_subnet->responselist != NULL)
- {
- DEBUG(0,("find_response_record: response record found on subnet %s. This should \
-never happen !\n", remote_broadcast_subnet->subnet_name));
- }
-
- /* Now check the WINS server subnet if it exists. */
- if(wins_server_subnet != NULL)
- {
- *ppsubrec = wins_server_subnet;
- if((rrec = find_response_record_on_subnet(*ppsubrec, id))!= NULL)
- return rrec;
- }
-
- DEBUG(0,("find_response_record: response packet id %hu received with no \
-matching record.\n", id));
-
- *ppsubrec = NULL;
-
- return NULL;
-}
-
-/****************************************************************************
- Check if a refresh is queued for a particular name on a particular subnet.
- **************************************************************************/
-
-BOOL is_refresh_already_queued(struct subnet_record *subrec, struct name_record *namerec)
-{
- struct response_record *rrec = NULL;
-
- for (rrec = subrec->responselist; rrec; rrec = rrec->next)
- {
- struct packet_struct *p = rrec->packet;
- struct nmb_packet *nmb = &p->packet.nmb;
-
- if((nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
- (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9))
- {
- /* Yes it's a queued refresh - check if the name is correct. */
- if(nmb_name_equal(&nmb->question.question_name, &namerec->name))
- return True;
- }
- }
-
- return False;
-}
diff --git a/source4/nmbd/nmbd_sendannounce.c b/source4/nmbd/nmbd_sendannounce.c
deleted file mode 100644
index 191a3b7c7b..0000000000
--- a/source4/nmbd/nmbd_sendannounce.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
-
- SMB Version handling
- Copyright (C) John H Terpstra 1995-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"
-
-extern int updatecount;
-extern BOOL found_lm_clients;
-
-/****************************************************************************
- Send a browser reset packet.
-**************************************************************************/
-
-void send_browser_reset(int reset_type, const char *to_name, int to_type, struct in_addr to_ip)
-{
- pstring outbuf;
- char *p;
-
- DEBUG(3,("send_browser_reset: sending reset request type %d to %s<%02x> IP %s.\n",
- reset_type, to_name, to_type, inet_ntoa(to_ip) ));
-
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_ResetBrowserState);
- p++;
- SCVAL(p,0,reset_type);
- p++;
-
- send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- lp_netbios_name(), 0x0, to_name, to_type, to_ip,
- FIRST_SUBNET->myip, DGRAM_PORT);
-}
-
-/****************************************************************************
- Broadcast a packet to the local net requesting that all servers in this
- workgroup announce themselves to us.
- **************************************************************************/
-
-void broadcast_announce_request(struct subnet_record *subrec, struct work_record *work)
-{
- pstring outbuf;
- char *p;
-
- work->needannounce = True;
-
- DEBUG(3,("broadcast_announce_request: sending announce request for workgroup %s \
-to subnet %s\n", work->work_group, subrec->subnet_name));
-
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_AnnouncementRequest);
- p++;
-
- SCVAL(p,0,work->token); /* (local) Unique workgroup token id. */
- p++;
- p += push_string(NULL, p+1, lp_netbios_name(), 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
-
- send_mailslot(False, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- lp_netbios_name(), 0x0, work->work_group,0x1e, subrec->bcast_ip,
- subrec->myip, DGRAM_PORT);
-}
-
-/****************************************************************************
- Broadcast an announcement.
- **************************************************************************/
-
-static void send_announcement(struct subnet_record *subrec, int announce_type,
- const char *from_name, const char *to_name, int to_type, struct in_addr to_ip,
- time_t announce_interval,
- const char *server_name, int server_type, const char *server_comment)
-{
- pstring outbuf;
- char *p;
-
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf+1;
-
- SCVAL(outbuf,0,announce_type);
-
- /* Announcement parameters. */
- SCVAL(p,0,updatecount);
- SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */
-
- push_string(NULL, p+5, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
-
- SCVAL(p,21,lp_major_announce_version()); /* Major version. */
- SCVAL(p,22,lp_minor_announce_version()); /* Minor version. */
-
- SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
- /* Browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT). */
- SSVAL(p,27,BROWSER_ELECTION_VERSION);
- SSVAL(p,29,BROWSER_CONSTANT); /* Browse signature. */
-
- p += 31 + push_string(NULL, p+31, server_comment, -1, STR_ASCII|STR_TERMINATE);
-
- send_mailslot(False,BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
- from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
- DGRAM_PORT);
-}
-
-/****************************************************************************
- Broadcast a LanMan announcement.
-**************************************************************************/
-
-static void send_lm_announcement(struct subnet_record *subrec, int announce_type,
- char *from_name, char *to_name, int to_type, struct in_addr to_ip,
- time_t announce_interval,
- char *server_name, int server_type, char *server_comment)
-{
- pstring outbuf;
- char *p=outbuf;
-
- memset(outbuf,'\0',sizeof(outbuf));
-
- SSVAL(p,0,announce_type);
- SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
- SCVAL(p,6,lp_major_announce_version()); /* Major version. */
- SCVAL(p,7,lp_minor_announce_version()); /* Minor version. */
- SSVAL(p,8,announce_interval); /* In seconds - according to spec. */
-
- p += 10;
- /*StrnCpy(p,server_name,15);
- strupper(p);
- p = skip_string(p,1);
- pstrcpy(p,server_comment);
- p = skip_string(p,1);*/
- p += push_string(NULL, p, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
- p += push_string(NULL, p, server_comment, sizeof(pstring)-15, STR_ASCII|STR_UPPER|STR_TERMINATE);
-
- send_mailslot(False,LANMAN_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
- from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
- DGRAM_PORT);
-}
-
-/****************************************************************************
- We are a local master browser. Announce this to WORKGROUP<1e>.
-****************************************************************************/
-
-static void send_local_master_announcement(struct subnet_record *subrec, struct work_record *work,
- struct server_record *servrec)
-{
- /* Ensure we don't have the prohibited bit set. */
- uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
-
- DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
- type, lp_netbios_name(), subrec->subnet_name, work->work_group));
-
- send_announcement(subrec, ANN_LocalMasterAnnouncement,
- lp_netbios_name(), /* From nbt name. */
- work->work_group, 0x1e, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- work->announce_interval, /* Time until next announce. */
- lp_netbios_name(), /* Name to announce. */
- type, /* Type field. */
- servrec->serv.comment);
-}
-
-/****************************************************************************
- Announce the workgroup WORKGROUP to MSBROWSE<01>.
-****************************************************************************/
-
-static void send_workgroup_announcement(struct subnet_record *subrec, struct work_record *work)
-{
- DEBUG(3,("send_workgroup_announcement: on subnet %s for workgroup %s\n",
- subrec->subnet_name, work->work_group));
-
- send_announcement(subrec, ANN_DomainAnnouncement,
- lp_netbios_name(), /* From nbt name. */
- MSBROWSE, 0x1, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- work->announce_interval, /* Time until next announce. */
- work->work_group, /* Name to announce. */
- SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT, /* workgroup announce flags. */
- lp_netbios_name()); /* From name as comment. */
-}
-
-/****************************************************************************
- Announce the given host to WORKGROUP<1d>.
-****************************************************************************/
-
-static void send_host_announcement(struct subnet_record *subrec, struct work_record *work,
- struct server_record *servrec)
-{
- /* Ensure we don't have the prohibited bits set. */
- uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
-
- DEBUG(3,("send_host_announcement: type %x for host %s on subnet %s for workgroup %s\n",
- type, servrec->serv.name, subrec->subnet_name, work->work_group));
-
- send_announcement(subrec, ANN_HostAnnouncement,
- servrec->serv.name, /* From nbt name. */
- work->work_group, 0x1d, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- work->announce_interval, /* Time until next announce. */
- servrec->serv.name, /* Name to announce. */
- type, /* Type field. */
- servrec->serv.comment);
-}
-
-/****************************************************************************
- Announce the given LanMan host
-****************************************************************************/
-
-static void send_lm_host_announcement(struct subnet_record *subrec, struct work_record *work,
- struct server_record *servrec, int lm_interval)
-{
- /* Ensure we don't have the prohibited bits set. */
- uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
-
- DEBUG(3,("send_lm_host_announcement: type %x for host %s on subnet %s for workgroup %s, ttl: %d\n",
- type, servrec->serv.name, subrec->subnet_name, work->work_group, lm_interval));
-
- send_lm_announcement(subrec, ANN_HostAnnouncement,
- servrec->serv.name, /* From nbt name. */
- work->work_group, 0x00, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- lm_interval, /* Time until next announce. */
- servrec->serv.name, /* Name to announce. */
- type, /* Type field. */
- servrec->serv.comment);
-}
-
-/****************************************************************************
- Announce a server record.
- ****************************************************************************/
-
-static void announce_server(struct subnet_record *subrec, struct work_record *work,
- struct server_record *servrec)
-{
- /* Only do domain announcements if we are a master and it's
- our primary name we're being asked to announce. */
-
- if (AM_LOCAL_MASTER_BROWSER(work) && strequal(lp_netbios_name(),servrec->serv.name))
- {
- send_local_master_announcement(subrec, work, servrec);
- send_workgroup_announcement(subrec, work);
- }
- else
- {
- send_host_announcement(subrec, work, servrec);
- }
-}
-
-/****************************************************************************
- Go through all my registered names on all broadcast subnets and announce
- them if the timeout requires it.
- **************************************************************************/
-
-void announce_my_server_names(time_t t)
-{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
-
- if(work)
- {
- struct server_record *servrec;
-
- if (work->needannounce)
- {
- /* Drop back to a max 3 minute announce. This is to prevent a
- single lost packet from breaking things for too long. */
-
- work->announce_interval = MIN(work->announce_interval,
- CHECK_TIME_MIN_HOST_ANNCE*60);
- work->lastannounce_time = t - (work->announce_interval+1);
- work->needannounce = False;
- }
-
- /* Announce every minute at first then progress to every 12 mins */
- if ((t - work->lastannounce_time) < work->announce_interval)
- continue;
-
- if (work->announce_interval < (CHECK_TIME_MAX_HOST_ANNCE * 60))
- work->announce_interval += 60;
-
- work->lastannounce_time = t;
-
- for (servrec = work->serverlist; servrec; servrec = servrec->next)
- {
- if (is_myname(servrec->serv.name))
- announce_server(subrec, work, servrec);
- }
- } /* if work */
- } /* for subrec */
-}
-
-/****************************************************************************
- Go through all my registered names on all broadcast subnets and announce
- them as a LanMan server if the timeout requires it.
-**************************************************************************/
-
-void announce_my_lm_server_names(time_t t)
-{
- struct subnet_record *subrec;
- static time_t last_lm_announce_time=0;
- int announce_interval = lp_lm_interval();
- int lm_announce = lp_lm_announce();
-
- if ((announce_interval <= 0) || (lm_announce <= 0))
- {
- /* user absolutely does not want LM announcements to be sent. */
- return;
- }
-
- if ((lm_announce >= 2) && (!found_lm_clients))
- {
- /* has been set to 2 (Auto) but no LM clients detected (yet). */
- return;
- }
-
- /* Otherwise: must have been set to 1 (Yes), or LM clients *have*
- been detected. */
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
-
- if(work)
- {
- struct server_record *servrec;
-
- if (last_lm_announce_time && ((t - last_lm_announce_time) < announce_interval ))
- continue;
-
- last_lm_announce_time = t;
-
- for (servrec = work->serverlist; servrec; servrec = servrec->next)
- {
- if (is_myname(servrec->serv.name))
- /* skipping equivalent of announce_server() */
- send_lm_host_announcement(subrec, work, servrec, announce_interval);
- }
- } /* if work */
- } /* for subrec */
-}
-
-/* Announce timer. Moved into global static so it can be reset
- when a machine becomes a local master browser. */
-static time_t announce_timer_last=0;
-
-/****************************************************************************
- Reset the announce_timer so that a local master browser announce will be done
- immediately.
- ****************************************************************************/
-
-void reset_announce_timer(void)
-{
- announce_timer_last = time(NULL) - (CHECK_TIME_MST_ANNOUNCE * 60);
-}
-
-/****************************************************************************
- Announce myself as a local master browser to a domain master browser.
- **************************************************************************/
-
-void announce_myself_to_domain_master_browser(time_t t)
-{
- struct subnet_record *subrec;
- struct work_record *work;
-
- if(!we_are_a_wins_client())
- {
- DEBUG(10,("announce_myself_to_domain_master_browser: no unicast subnet, ignoring.\n"));
- return;
- }
-
- if (!announce_timer_last)
- announce_timer_last = t;
-
- if ((t-announce_timer_last) < (CHECK_TIME_MST_ANNOUNCE * 60))
- {
- DEBUG(10,("announce_myself_to_domain_master_browser: t (%d) - last(%d) < %d\n",
- (int)t, (int)announce_timer_last,
- CHECK_TIME_MST_ANNOUNCE * 60 ));
- return;
- }
-
- announce_timer_last = t;
-
- /* Look over all our broadcast subnets to see if any of them
- has the state set as local master browser. */
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- if (AM_LOCAL_MASTER_BROWSER(work))
- {
- DEBUG(4,( "announce_myself_to_domain_master_browser: I am a local master browser for \
-workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
-
- /* Look in nmbd_browsersync.c for the rest of this code. */
- announce_and_sync_with_domain_master_browser(subrec, work);
- }
- }
- }
-}
-
-/****************************************************************************
-Announce all samba's server entries as 'gone'.
-This must *only* be called on shutdown.
-****************************************************************************/
-
-void announce_my_servers_removed(void)
-{
- int announce_interval = lp_lm_interval();
- int lm_announce = lp_lm_announce();
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- struct server_record *servrec;
-
- work->announce_interval = 0;
- for (servrec = work->serverlist; servrec; servrec = servrec->next)
- {
- if (!is_myname(servrec->serv.name))
- continue;
- servrec->serv.type = 0;
- if(AM_LOCAL_MASTER_BROWSER(work))
- send_local_master_announcement(subrec, work, servrec);
- send_host_announcement(subrec, work, servrec);
-
-
- if ((announce_interval <= 0) || (lm_announce <= 0))
- {
- /* user absolutely does not want LM announcements to be sent. */
- continue;
- }
-
- if ((lm_announce >= 2) && (!found_lm_clients))
- {
- /* has been set to 2 (Auto) but no LM clients detected (yet). */
- continue;
- }
-
- /*
- * lm announce was set or we have seen lm announcements, so do
- * a lm announcement of host removed.
- */
-
- send_lm_host_announcement(subrec, work, servrec, 0);
- }
- }
- }
-}
-
-/****************************************************************************
- Do all the "remote" announcements. These are used to put ourselves
- on a remote browse list. They are done blind, no checking is done to
- see if there is actually a local master browser at the other end.
- **************************************************************************/
-
-void announce_remote(time_t t)
-{
- char *s;
- const char *ptr;
- static time_t last_time = 0;
- pstring s2;
- struct in_addr addr;
- char *comment;
- int stype = lp_default_server_announce();
-
- if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
- return;
-
- last_time = t;
-
- s = lp_remote_announce();
- if (!*s)
- return;
-
- comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH);
-
- for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); )
- {
- /* The entries are of the form a.b.c.d/WORKGROUP with
- WORKGROUP being optional */
- const char *wgroup;
- char *pwgroup;
- int i;
-
- pwgroup = strchr_m(s2,'/');
- if (pwgroup)
- *pwgroup++ = 0;
- if (!pwgroup || !*pwgroup)
- wgroup = lp_workgroup();
- else
- wgroup = pwgroup;
-
- addr = *interpret_addr2(s2);
-
- /* Announce all our names including aliases */
- /* Give the ip address as the address of our first
- broadcast subnet. */
-
- for(i=0; my_netbios_names(i); i++)
- {
- const char *name = my_netbios_names(i);
-
- DEBUG(5,("announce_remote: Doing remote announce for server %s to IP %s.\n",
- name, inet_ntoa(addr) ));
-
- send_announcement(FIRST_SUBNET, ANN_HostAnnouncement,
- name, /* From nbt name. */
- wgroup, 0x1d, /* To nbt name. */
- addr, /* To ip. */
- REMOTE_ANNOUNCE_INTERVAL, /* Time until next announce. */
- name, /* Name to announce. */
- stype, /* Type field. */
- comment);
- }
- }
-}
-
-/****************************************************************************
- Implement the 'remote browse sync' feature Andrew added.
- These are used to put our browse lists into remote browse lists.
- **************************************************************************/
-
-void browse_sync_remote(time_t t)
-{
- char *s;
- const char *ptr;
- static time_t last_time = 0;
- pstring s2;
- struct in_addr addr;
- struct work_record *work;
- pstring outbuf;
- char *p;
-
- if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
- return;
-
- last_time = t;
-
- s = lp_remote_browse_sync();
- if (!*s)
- return;
-
- /*
- * We only do this if we are the local master browser
- * for our workgroup on the firsst subnet.
- */
-
- if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL)
- {
- DEBUG(0,("browse_sync_remote: Cannot find workgroup %s on subnet %s\n",
- lp_workgroup(), FIRST_SUBNET->subnet_name ));
- return;
- }
-
- if(!AM_LOCAL_MASTER_BROWSER(work))
- {
- DEBUG(5,("browse_sync_remote: We can only do this if we are a local master browser \
-for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name ));
- return;
- }
-
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_MasterAnnouncement);
- p++;
-
- StrnCpy(p,lp_netbios_name(),15);
- strupper(p);
- p = skip_string(p,1);
-
- for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); )
- {
- /* The entries are of the form a.b.c.d */
- addr = *interpret_addr2(s2);
-
- DEBUG(5,("announce_remote: Doing remote browse sync announce for server %s to IP %s.\n",
- lp_netbios_name(), inet_ntoa(addr) ));
-
- send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- lp_netbios_name(), 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT);
- }
-}
diff --git a/source4/nmbd/nmbd_serverlistdb.c b/source4/nmbd/nmbd_serverlistdb.c
deleted file mode 100644
index ee0c021d5d..0000000000
--- a/source4/nmbd/nmbd_serverlistdb.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-extern int ClientNMB;
-
-int updatecount = 0;
-
-/*******************************************************************
- Remove all the servers in a work group.
- ******************************************************************/
-
-void remove_all_servers(struct work_record *work)
-{
- struct server_record *servrec;
- struct server_record *nexts;
-
- for (servrec = work->serverlist; servrec; servrec = nexts)
- {
- DEBUG(7,("remove_all_servers: Removing server %s\n",servrec->serv.name));
- nexts = servrec->next;
-
- if (servrec->prev)
- servrec->prev->next = servrec->next;
- if (servrec->next)
- servrec->next->prev = servrec->prev;
-
- if (work->serverlist == servrec)
- work->serverlist = servrec->next;
-
- ZERO_STRUCTP(servrec);
- SAFE_FREE(servrec);
-
- }
-
- work->subnet->work_changed = True;
-}
-
-/***************************************************************************
- Add a server into the a workgroup serverlist.
- **************************************************************************/
-
-static void add_server_to_workgroup(struct work_record *work,
- struct server_record *servrec)
-{
- struct server_record *servrec2;
-
- if (!work->serverlist)
- {
- work->serverlist = servrec;
- servrec->prev = NULL;
- servrec->next = NULL;
- return;
- }
-
- for (servrec2 = work->serverlist; servrec2->next; servrec2 = servrec2->next)
- ;
-
- servrec2->next = servrec;
- servrec->next = NULL;
- servrec->prev = servrec2;
- work->subnet->work_changed = True;
-}
-
-/****************************************************************************
- Find a server in a server list.
- **************************************************************************/
-
-struct server_record *find_server_in_workgroup(struct work_record *work, const char *name)
-{
- struct server_record *ret;
-
- for (ret = work->serverlist; ret; ret = ret->next)
- {
- if (strequal(ret->serv.name,name))
- return ret;
- }
- return NULL;
-}
-
-
-/****************************************************************************
- Remove a server entry from this workgroup.
- ****************************************************************************/
-
-void remove_server_from_workgroup(struct work_record *work, struct server_record *servrec)
-{
- if (servrec->prev)
- servrec->prev->next = servrec->next;
- if (servrec->next)
- servrec->next->prev = servrec->prev;
-
- if (work->serverlist == servrec)
- work->serverlist = servrec->next;
-
- ZERO_STRUCTP(servrec);
- SAFE_FREE(servrec);
- work->subnet->work_changed = True;
-}
-
-/****************************************************************************
- Create a server entry on this workgroup.
- ****************************************************************************/
-
-struct server_record *create_server_on_workgroup(struct work_record *work,
- const char *name,int servertype,
- int ttl, const char *comment)
-{
- struct server_record *servrec;
-
- if (name[0] == '*')
- {
- DEBUG(7,("create_server_on_workgroup: not adding name starting with '*' (%s)\n",
- name));
- return (NULL);
- }
-
- if((servrec = find_server_in_workgroup(work, name)) != NULL)
- {
- DEBUG(0,("create_server_on_workgroup: Server %s already exists on \
-workgroup %s. This is a bug.\n", name, work->work_group));
- return NULL;
- }
-
- if((servrec = (struct server_record *)malloc(sizeof(*servrec))) == NULL)
- {
- DEBUG(0,("create_server_entry_on_workgroup: malloc fail !\n"));
- return NULL;
- }
-
- memset((char *)servrec,'\0',sizeof(*servrec));
-
- servrec->subnet = work->subnet;
-
- StrnCpy(servrec->serv.name,name,sizeof(servrec->serv.name)-1);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
- strupper(servrec->serv.name);
- servrec->serv.type = servertype;
-
- update_server_ttl(servrec, ttl);
-
- add_server_to_workgroup(work, servrec);
-
- DEBUG(3,("create_server_on_workgroup: Created server entry %s of type %x (%s) on \
-workgroup %s.\n", name,servertype,comment, work->work_group));
-
- work->subnet->work_changed = True;
-
- return(servrec);
-}
-
-/*******************************************************************
- Update the ttl field of a server record.
-*******************************************************************/
-
-void update_server_ttl(struct server_record *servrec, int ttl)
-{
- if(ttl > lp_max_ttl())
- ttl = lp_max_ttl();
-
- if(is_myname(servrec->serv.name))
- servrec->death_time = PERMANENT_TTL;
- else
- servrec->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;
-
- servrec->subnet->work_changed = True;
-}
-
-/*******************************************************************
- Expire old servers in the serverlist. A time of -1 indicates
- everybody dies except those with a death_time of PERMANENT_TTL (which is 0).
- This should only be called from expire_workgroups_and_servers().
- ******************************************************************/
-
-void expire_servers(struct work_record *work, time_t t)
-{
- struct server_record *servrec;
- struct server_record *nexts;
-
- for (servrec = work->serverlist; servrec; servrec = nexts)
- {
- nexts = servrec->next;
-
- if ((servrec->death_time != PERMANENT_TTL) && ((t == -1) || (servrec->death_time < t)))
- {
- DEBUG(3,("expire_old_servers: Removing timed out server %s\n",servrec->serv.name));
- remove_server_from_workgroup(work, servrec);
- work->subnet->work_changed = True;
- }
- }
-}
-
-/*******************************************************************
- Decide if we should write out a server record for this server.
- We return zero if we should not. Check if we've already written
- out this server record from an earlier subnet.
-******************************************************************/
-
-static uint32 write_this_server_name( struct subnet_record *subrec,
- struct work_record *work,
- struct server_record *servrec)
-{
- struct subnet_record *ssub;
- struct work_record *iwork;
-
- /* Go through all the subnets we have already seen. */
- for (ssub = FIRST_SUBNET; ssub != subrec; ssub = NEXT_SUBNET_INCLUDING_UNICAST(ssub))
- {
- for(iwork = ssub->workgrouplist; iwork; iwork = iwork->next)
- {
- if(find_server_in_workgroup( iwork, servrec->serv.name) != NULL)
- {
- /*
- * We have already written out this server record, don't
- * do it again. This gives precedence to servers we have seen
- * on the broadcast subnets over servers that may have been
- * added via a sync on the unicast_subet.
- *
- * The correct way to do this is to have a serverlist file
- * per subnet - this means changes to smbd as well. I may
- * add this at a later date (JRA).
- */
-
- return 0;
- }
- }
- }
-
- return servrec->serv.type;
-}
-
-/*******************************************************************
- Decide if we should write out a workgroup record for this workgroup.
- We return zero if we should not. Don't write out lp_workgroup() (we've
- already done it) and also don't write out a second workgroup record
- on the unicast subnet that we've already written out on one of the
- broadcast subnets.
-******************************************************************/
-
-static uint32 write_this_workgroup_name( struct subnet_record *subrec,
- struct work_record *work)
-{
- struct subnet_record *ssub;
-
- if(strequal(lp_workgroup(), work->work_group))
- return 0;
-
- /* This is a workgroup we have seen on a broadcast subnet. All
- these have the same type. */
-
- if(subrec != unicast_subnet)
- return (SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY);
-
- for(ssub = FIRST_SUBNET; ssub; ssub = NEXT_SUBNET_EXCLUDING_UNICAST(ssub))
- {
- /* This is the unicast subnet so check if we've already written out
- this subnet when we passed over the broadcast subnets. */
-
- if(find_workgroup_on_subnet( ssub, work->work_group) != NULL)
- return 0;
- }
-
- /* All workgroups on the unicast subnet (except our own, which we
- have already written out) cannot be local. */
-
- return (SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT);
-}
-
-/*******************************************************************
- Write out the browse.dat file.
- ******************************************************************/
-
-void write_browse_list_entry(XFILE *fp, const char *name, uint32 rec_type,
- const char *local_master_browser_name, const char *description)
-{
- fstring tmp;
-
- slprintf(tmp,sizeof(tmp)-1, "\"%s\"", name);
- x_fprintf(fp, "%-25s ", tmp);
- x_fprintf(fp, "%08x ", rec_type);
- slprintf(tmp, sizeof(tmp)-1, "\"%s\" ", local_master_browser_name);
- x_fprintf(fp, "%-30s", tmp);
- x_fprintf(fp, "\"%s\"\n", description);
-}
-
-void write_browse_list(time_t t, BOOL force_write)
-{
- struct subnet_record *subrec;
- struct work_record *work;
- struct server_record *servrec;
- pstring fname,fnamenew;
- uint32 stype;
- int i;
- XFILE *fp;
- BOOL list_changed = force_write;
- static time_t lasttime = 0;
-
- /* Always dump if we're being told to by a signal. */
- if(force_write == False)
- {
- if (!lasttime)
- lasttime = t;
- if (t - lasttime < 5)
- return;
- }
-
- lasttime = t;
-
- dump_workgroups(force_write);
-
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- if(subrec->work_changed)
- {
- list_changed = True;
- break;
- }
- }
-
- if(!list_changed)
- return;
-
- updatecount++;
-
- pstrcpy(fname,lp_lockdir());
- trim_string(fname,NULL,"/");
- pstrcat(fname,"/");
- pstrcat(fname,SERVER_LIST);
- pstrcpy(fnamenew,fname);
- pstrcat(fnamenew,".");
-
- fp = x_fopen(fnamenew,O_WRONLY|O_CREAT|O_TRUNC, 0644);
-
- if (!fp)
- {
- DEBUG(0,("write_browse_list: Can't open file %s. Error was %s\n",
- fnamenew,strerror(errno)));
- return;
- }
-
- /*
- * Write out a record for our workgroup. Use the record from the first
- * subnet.
- */
-
- if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL)
- {
- DEBUG(0,("write_browse_list: Fatal error - cannot find my workgroup %s\n",
- lp_workgroup()));
- x_fclose(fp);
- return;
- }
-
- write_browse_list_entry(fp, work->work_group,
- SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY,
- work->local_master_browser_name, work->work_group);
-
- /*
- * We need to do something special for our own names.
- * This is due to the fact that we may be a local master browser on
- * one of our broadcast subnets, and a domain master on the unicast
- * subnet. We iterate over the subnets and only write out the name
- * once.
- */
-
- for (i=0; my_netbios_names(i); i++)
- {
- stype = 0;
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- if((work = find_workgroup_on_subnet( subrec, lp_workgroup() )) == NULL)
- continue;
- if((servrec = find_server_in_workgroup( work, my_netbios_names(i))) == NULL)
- continue;
-
- stype |= servrec->serv.type;
- }
-
- /* Output server details, plus what workgroup they're in. */
- write_browse_list_entry(fp, my_netbios_names(i), stype,
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), lp_workgroup());
- }
-
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- subrec->work_changed = False;
-
- for (work = subrec->workgrouplist; work ; work = work->next)
- {
- /* Write out a workgroup record for a workgroup. */
- uint32 wg_type = write_this_workgroup_name( subrec, work);
-
- if(wg_type)
- {
- write_browse_list_entry(fp, work->work_group, wg_type,
- work->local_master_browser_name,
- work->work_group);
- }
-
- /* Now write out any server records a workgroup may have. */
-
- for (servrec = work->serverlist; servrec ; servrec = servrec->next)
- {
- uint32 serv_type;
-
- /* We have already written our names here. */
- if(is_myname(servrec->serv.name))
- continue;
-
- serv_type = write_this_server_name(subrec, work, servrec);
-
- if(serv_type)
- {
- /* Output server details, plus what workgroup they're in. */
- write_browse_list_entry(fp, servrec->serv.name, serv_type,
- servrec->serv.comment, work->work_group);
- }
- }
- }
- }
-
- x_fclose(fp);
- unlink(fname);
- chmod(fnamenew,0644);
- rename(fnamenew,fname);
- DEBUG(3,("write_browse_list: Wrote browse list into file %s\n",fname));
-}
diff --git a/source4/nmbd/nmbd_subnetdb.c b/source4/nmbd/nmbd_subnetdb.c
deleted file mode 100644
index 6296826425..0000000000
--- a/source4/nmbd/nmbd_subnetdb.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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.
-
- Revision History:
-
-*/
-
-#include "includes.h"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-extern int global_nmb_port;
-
-/* This is the broadcast subnets database. */
-struct subnet_record *subnetlist = NULL;
-
-/* Extra subnets - keep these separate so enumeration code doesn't
- run onto it by mistake. */
-
-struct subnet_record *unicast_subnet = NULL;
-struct subnet_record *remote_broadcast_subnet = NULL;
-struct subnet_record *wins_server_subnet = NULL;
-
-extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
-
-/****************************************************************************
- Add a subnet into the list.
- **************************************************************************/
-
-static void add_subnet(struct subnet_record *subrec)
-{
- DLIST_ADD(subnetlist, subrec);
-}
-
-/* ************************************************************************** **
- * Comparison routine for ordering the splay-tree based namelists assoicated
- * with each subnet record.
- *
- * Input: Item - Pointer to the comparison key.
- * Node - Pointer to a node the splay tree.
- *
- * Output: The return value will be <0 , ==0, or >0 depending upon the
- * ordinal relationship of the two keys.
- *
- * ************************************************************************** **
- */
-static int namelist_entry_compare( ubi_trItemPtr Item, ubi_trNodePtr Node )
- {
- struct name_record *NR = (struct name_record *)Node;
-
- if( DEBUGLVL( 10 ) )
- {
- struct nmb_name *Iname = (struct nmb_name *)Item;
-
- Debug1( "nmbd_subnetdb:namelist_entry_compare()\n" );
- Debug1( "%d == memcmp( \"%s\", \"%s\", %d )\n",
- memcmp( Item, &(NR->name), sizeof(struct nmb_name) ),
- nmb_namestr(Iname), nmb_namestr(&NR->name), (int)sizeof(struct nmb_name) );
- }
-
- return( memcmp( Item, &(NR->name), sizeof(struct nmb_name) ) );
- } /* namelist_entry_compare */
-
-
-/****************************************************************************
-stop listening on a subnet
-we don't free the record as we don't have proper reference counting for it
-yet and it may be in use by a response record
- ****************************************************************************/
-void close_subnet(struct subnet_record *subrec)
-{
- DLIST_REMOVE(subnetlist, subrec);
-
- if (subrec->dgram_sock != -1) {
- close(subrec->dgram_sock);
- subrec->dgram_sock = -1;
- }
- if (subrec->nmb_sock != -1) {
- close(subrec->nmb_sock);
- subrec->nmb_sock = -1;
- }
-}
-
-
-
-/****************************************************************************
- Create a subnet entry.
- ****************************************************************************/
-
-static struct subnet_record *make_subnet(const char *name, enum subnet_type type,
- struct in_addr myip, struct in_addr bcast_ip,
- struct in_addr mask_ip)
-{
- struct subnet_record *subrec = NULL;
- int nmb_sock, dgram_sock;
-
- /* Check if we are creating a non broadcast subnet - if so don't create
- sockets.
- */
-
- if(type != NORMAL_SUBNET)
- {
- nmb_sock = -1;
- dgram_sock = -1;
- }
- else
- {
- /*
- * Attempt to open the sockets on port 137/138 for this interface
- * and bind them.
- * Fail the subnet creation if this fails.
- */
-
- if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1)
- {
- if( DEBUGLVL( 0 ) )
- {
- Debug1( "nmbd_subnetdb:make_subnet()\n" );
- Debug1( " Failed to open nmb socket on interface %s ", inet_ntoa(myip) );
- Debug1( "for port %d. ", global_nmb_port );
- Debug1( "Error was %s\n", strerror(errno) );
- }
- return NULL;
- }
-
- if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1)
- {
- if( DEBUGLVL( 0 ) )
- {
- Debug1( "nmbd_subnetdb:make_subnet()\n" );
- Debug1( " Failed to open dgram socket on interface %s ", inet_ntoa(myip) );
- Debug1( "for port %d. ", DGRAM_PORT );
- Debug1( "Error was %s\n", strerror(errno) );
- }
- return NULL;
- }
-
- /* Make sure we can broadcast from these sockets. */
- set_socket_options(nmb_sock,"SO_BROADCAST");
- set_socket_options(dgram_sock,"SO_BROADCAST");
-
- }
-
- subrec = (struct subnet_record *)malloc(sizeof(*subrec));
-
- if (!subrec)
- {
- DEBUG(0,("make_subnet: malloc fail !\n"));
- close(nmb_sock);
- close(dgram_sock);
- return(NULL);
- }
-
- memset( (char *)subrec, '\0', sizeof(*subrec) );
- (void)ubi_trInitTree( subrec->namelist,
- namelist_entry_compare,
- ubi_trOVERWRITE );
-
- if((subrec->subnet_name = strdup(name)) == NULL)
- {
- DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
- close(nmb_sock);
- close(dgram_sock);
- ZERO_STRUCTP(subrec);
- SAFE_FREE(subrec);
- return(NULL);
- }
-
- DEBUG(2, ("making subnet name:%s ", name ));
- DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip)));
- DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip)));
-
- subrec->namelist_changed = False;
- subrec->work_changed = False;
-
- subrec->bcast_ip = bcast_ip;
- subrec->mask_ip = mask_ip;
- subrec->myip = myip;
- subrec->type = type;
- subrec->nmb_sock = nmb_sock;
- subrec->dgram_sock = dgram_sock;
-
- return subrec;
-}
-
-
-/****************************************************************************
- Create a normal subnet
-**************************************************************************/
-struct subnet_record *make_normal_subnet(struct interface *iface)
-{
- struct subnet_record *subrec;
-
- subrec = make_subnet(inet_ntoa(iface->ip), NORMAL_SUBNET,
- iface->ip, iface->bcast, iface->nmask);
- if (subrec) {
- add_subnet(subrec);
- }
- return subrec;
-}
-
-
-/****************************************************************************
- Create subnet entries.
-**************************************************************************/
-
-BOOL create_subnets(void)
-{
- int num_interfaces = iface_count();
- int i;
- struct in_addr unicast_ip, ipzero;
- extern struct in_addr loopback_ip;
-
- if(num_interfaces == 0) {
- DEBUG(0,("create_subnets: No local interfaces !\n"));
- DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
- while (iface_count() == 0) {
- sleep(5);
- load_interfaces();
- }
- }
-
- num_interfaces = iface_count();
-
- /*
- * Create subnets from all the local interfaces and thread them onto
- * the linked list.
- */
-
- for (i = 0 ; i < num_interfaces; i++)
- {
- struct interface *iface = get_interface(i);
-
- /*
- * We don't want to add a loopback interface, in case
- * someone has added 127.0.0.1 for smbd, nmbd needs to
- * ignore it here. JRA.
- */
-
- if (ip_equal(iface->ip, loopback_ip)) {
- DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
- continue;
- }
-
- if (!make_normal_subnet(iface)) return False;
- }
-
- if (lp_we_are_a_wins_server()) {
- /* Pick the first interface ip address as the WINS server ip. */
- unicast_ip = *iface_n_ip(0);
- } else {
- /* note that we do not set the wins server IP here. We just
- set it at zero and let the wins registration code cope
- with getting the IPs right for each packet */
- zero_ip(&unicast_ip);
- }
-
- /*
- * Create the unicast and remote broadcast subnets.
- * Don't put these onto the linked list.
- * The ip address of the unicast subnet is set to be
- * the WINS server address, if it exists, or ipzero if not.
- */
-
- unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET,
- unicast_ip, unicast_ip, unicast_ip);
-
- zero_ip(&ipzero);
-
- remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
- REMOTE_BROADCAST_SUBNET,
- ipzero, ipzero, ipzero);
-
- if((unicast_subnet == NULL) || (remote_broadcast_subnet == NULL))
- return False;
-
- /*
- * If we are WINS server, create the WINS_SERVER_SUBNET - don't put on
- * the linked list.
- */
-
- if (lp_we_are_a_wins_server())
- {
- if( (wins_server_subnet = make_subnet( "WINS_SERVER_SUBNET",
- WINS_SERVER_SUBNET,
- ipzero, ipzero, ipzero )) == NULL )
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
-Function to tell us if we can use the unicast subnet.
-******************************************************************/
-BOOL we_are_a_wins_client(void)
-{
- if (wins_srv_count() > 0) {
- return True;
- }
-
- return False;
-}
-
-/*******************************************************************
-Access function used by NEXT_SUBNET_INCLUDING_UNICAST
-******************************************************************/
-
-struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec)
-{
- if(subrec == unicast_subnet)
- return NULL;
- else if((subrec->next == NULL) && we_are_a_wins_client())
- return unicast_subnet;
- else
- return subrec->next;
-}
-
-/*******************************************************************
- Access function used by retransmit_or_expire_response_records() in
- nmbd_packets.c. Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>
- Needed when we need to enumerate all the broadcast, unicast and
- WINS subnets.
-******************************************************************/
-
-struct subnet_record *get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record *subrec)
-{
- if(subrec == unicast_subnet)
- {
- if(wins_server_subnet)
- return wins_server_subnet;
- else
- return NULL;
- }
-
- if(wins_server_subnet && subrec == wins_server_subnet)
- return NULL;
-
- if((subrec->next == NULL) && we_are_a_wins_client())
- return unicast_subnet;
- else
- return subrec->next;
-}
diff --git a/source4/nmbd/nmbd_synclists.c b/source4/nmbd/nmbd_synclists.c
deleted file mode 100644
index b9952fb446..0000000000
--- a/source4/nmbd/nmbd_synclists.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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.
-
-*/
-
-/* this file handles asynchronous browse synchronisation requests. The
- requests are done by forking and putting the result in a file in the
- locks directory. We do it this way because we don't want nmbd to be
- blocked waiting for some server to respond on a TCP connection. This
- also allows us to have more than 1 sync going at once (tridge) */
-
-#include "includes.h"
-
-struct sync_record {
- struct sync_record *next, *prev;
- fstring workgroup;
- fstring server;
- pstring fname;
- struct in_addr ip;
- pid_t pid;
-};
-
-/* a linked list of current sync connections */
-static struct sync_record *syncs;
-
-static XFILE *fp;
-
-/*******************************************************************
- This is the NetServerEnum callback.
- Note sname and comment are in UNIX codepage format.
- ******************************************************************/
-static void callback(const char *sname, uint32 stype,
- const char *comment, void *state)
-{
- x_fprintf(fp,"\"%s\" %08X \"%s\"\n", sname, stype, comment);
-}
-
-/*******************************************************************
- Synchronise browse lists with another browse server.
- Log in on the remote server's SMB port to their IPC$ service,
- do a NetServerEnum and record the results in fname
-******************************************************************/
-static void sync_child(char *name, int nm_type,
- char *workgroup,
- struct in_addr ip, BOOL local, BOOL servers,
- char *fname)
-{
- extern fstring local_machine;
- fstring unix_workgroup;
- static struct cli_state cli;
- uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
- struct nmb_name called, calling;
-
- /* W2K DMB's return empty browse lists on port 445. Use 139.
- * Patch from Andy Levine andyl@epicrealm.com.
- */
-
- if (!cli_initialise(&cli) || !cli_set_port(&cli, 139) || !cli_connect(&cli, name, &ip)) {
- return;
- }
-
- make_nmb_name(&calling, local_machine, 0x0);
- make_nmb_name(&called , name , nm_type);
-
- if (!cli_session_request(&cli, &calling, &called))
- {
- cli_shutdown(&cli);
- return;
- }
-
- if (!cli_negprot(&cli)) {
- cli_shutdown(&cli);
- return;
- }
-
- if (!cli_session_setup(&cli, "", "", 1, "", 0, workgroup)) {
- cli_shutdown(&cli);
- return;
- }
-
- if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
- cli_shutdown(&cli);
- return;
- }
-
- /* All the cli_XX functions take UNIX character set. */
- fstrcpy(unix_workgroup, cli.server_domain?cli.server_domain:workgroup);
-
- /* Fetch a workgroup list. */
- cli_NetServerEnum(&cli, unix_workgroup,
- local_type|SV_TYPE_DOMAIN_ENUM,
- callback, NULL);
-
- /* Now fetch a server list. */
- if (servers) {
- fstrcpy(unix_workgroup, workgroup);
- cli_NetServerEnum(&cli, unix_workgroup,
- local?SV_TYPE_LOCAL_LIST_ONLY:SV_TYPE_ALL,
- callback, NULL);
- }
-
- cli_shutdown(&cli);
-}
-
-
-/*******************************************************************
- initialise a browse sync with another browse server. Log in on the
- remote server's SMB port to their IPC$ service, do a NetServerEnum
- and record the results
-******************************************************************/
-void sync_browse_lists(struct work_record *work,
- char *name, int nm_type,
- struct in_addr ip, BOOL local, BOOL servers)
-{
- struct sync_record *s;
- static int counter;
-
- START_PROFILE(sync_browse_lists);
- /* Check we're not trying to sync with ourselves. This can
- happen if we are a domain *and* a local master browser. */
- if (ismyip(ip)) {
-done:
- END_PROFILE(sync_browse_lists);
- return;
- }
-
- s = (struct sync_record *)malloc(sizeof(*s));
- if (!s) goto done;
-
- ZERO_STRUCTP(s);
-
- fstrcpy(s->workgroup, work->work_group);
- fstrcpy(s->server, name);
- s->ip = ip;
-
- slprintf(s->fname, sizeof(pstring)-1,
- "%s/sync.%d", lp_lockdir(), counter++);
- all_string_sub(s->fname,"//", "/", 0);
-
- DLIST_ADD(syncs, s);
-
- /* the parent forks and returns, leaving the child to do the
- actual sync and call END_PROFILE*/
- CatchChild();
- if ((s->pid = sys_fork())) return;
-
- BlockSignals( False, SIGTERM );
-
- DEBUG(2,("Initiating browse sync for %s to %s(%s)\n",
- work->work_group, name, inet_ntoa(ip)));
-
- fp = x_fopen(s->fname,O_WRONLY|O_CREAT|O_TRUNC, 0644);
- if (!fp) {
- END_PROFILE(sync_browse_lists);
- _exit(1);
- }
-
- sync_child(name, nm_type, work->work_group, ip, local, servers,
- s->fname);
-
- x_fclose(fp);
- END_PROFILE(sync_browse_lists);
- _exit(0);
-}
-
-/**********************************************************************
-handle one line from a completed sync file
- **********************************************************************/
-static void complete_one(struct sync_record *s,
- char *sname, uint32 stype, char *comment)
-{
- struct work_record *work;
- struct server_record *servrec;
-
- stype &= ~SV_TYPE_LOCAL_LIST_ONLY;
-
- if (stype & SV_TYPE_DOMAIN_ENUM) {
- /* See if we can find the workgroup on this subnet. */
- if((work=find_workgroup_on_subnet(unicast_subnet, sname))) {
- /* We already know about this workgroup -
- update the ttl. */
- update_workgroup_ttl(work,lp_max_ttl());
- } else {
- /* Create the workgroup on the subnet. */
- work = create_workgroup_on_subnet(unicast_subnet,
- sname, lp_max_ttl());
- if (work) {
- /* remember who the master is */
- fstrcpy(work->local_master_browser_name,
- comment);
- }
- }
- return;
- }
-
- work = find_workgroup_on_subnet(unicast_subnet, s->workgroup);
- if (!work) {
- DEBUG(3,("workgroup %s doesn't exist on unicast subnet?\n",
- s->workgroup));
- return;
- }
-
- if ((servrec = find_server_in_workgroup( work, sname))) {
- /* Check that this is not a locally known
- server - if so ignore the entry. */
- if(!(servrec->serv.type & SV_TYPE_LOCAL_LIST_ONLY)) {
- /* We already know about this server - update
- the ttl. */
- update_server_ttl(servrec, lp_max_ttl());
- /* Update the type. */
- servrec->serv.type = stype;
- }
- return;
- }
-
- /* Create the server in the workgroup. */
- create_server_on_workgroup(work, sname,stype, lp_max_ttl(), comment);
-}
-
-
-/**********************************************************************
-read the completed sync info
- **********************************************************************/
-static void complete_sync(struct sync_record *s)
-{
- XFILE *f;
- fstring server, type_str;
- unsigned type;
- pstring comment;
- pstring line;
- const char *ptr;
- int count=0;
-
- f = x_fopen(s->fname,O_RDONLY, 0);
-
- if (!f) return;
-
- while (!x_feof(f)) {
-
- if (!fgets_slash(line,sizeof(pstring),f)) continue;
-
- ptr = line;
-
- if (!next_token(&ptr,server,NULL,sizeof(server)) ||
- !next_token(&ptr,type_str,NULL, sizeof(type_str)) ||
- !next_token(&ptr,comment,NULL, sizeof(comment))) {
- continue;
- }
-
- sscanf(type_str, "%X", &type);
-
- complete_one(s, server, type, comment);
-
- count++;
- }
-
- x_fclose(f);
-
- unlink(s->fname);
-
- DEBUG(2,("sync with %s(%s) for workgroup %s completed (%d records)\n",
- s->server, inet_ntoa(s->ip), s->workgroup, count));
-}
-
-/**********************************************************************
-check for completion of any of the child processes
- **********************************************************************/
-void sync_check_completion(void)
-{
- struct sync_record *s, *next;
-
- for (s=syncs;s;s=next) {
- next = s->next;
- if (!process_exists(s->pid)) {
- /* it has completed - grab the info */
- complete_sync(s);
- DLIST_REMOVE(syncs, s);
- ZERO_STRUCTP(s);
- SAFE_FREE(s);
- }
- }
-}
diff --git a/source4/nmbd/nmbd_winsproxy.c b/source4/nmbd/nmbd_winsproxy.c
deleted file mode 100644
index 2e65ebb612..0000000000
--- a/source4/nmbd/nmbd_winsproxy.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
-
- Copyright (C) Jeremy Allison 1994-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"
-
-/****************************************************************************
-Function called when the name lookup succeeded.
-****************************************************************************/
-
-static void wins_proxy_name_query_request_success( struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname, struct in_addr ip, struct res_rec *rrec)
-{
- struct packet_struct *original_packet;
- struct subnet_record *orig_broadcast_subnet;
- struct name_record *namerec;
- uint16 nb_flags;
- int num_ips;
- int i;
- int ttl = 3600; /* By default one hour in the cache. */
- struct in_addr *iplist;
-
- /* Extract the original packet and the original broadcast subnet from
- the userdata. */
-
- memcpy( (char *)&orig_broadcast_subnet, userdata->data, sizeof(struct subnet_record *) );
- memcpy( (char *)&original_packet, &userdata->data[sizeof(struct subnet_record *)],
- sizeof(struct packet_struct *) );
-
- nb_flags = get_nb_flags( rrec->rdata );
-
- num_ips = rrec->rdlength / 6;
- if(num_ips == 0)
- {
- DEBUG(0,("wins_proxy_name_query_request_success: Invalid number of IP records (0) \
-returned for name %s.\n", nmb_namestr(nmbname) ));
- return;
- }
-
- if(num_ips == 1)
- iplist = &ip;
- else
- {
- if((iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) )) == NULL)
- {
- DEBUG(0,("wins_proxy_name_query_request_success: malloc fail !\n"));
- return;
- }
-
- for(i = 0; i < num_ips; i++)
- putip( (char *)&iplist[i], (char *)&rrec->rdata[ (i*6) + 2]);
- }
-
- /* Add the queried name to the original subnet as a WINS_PROXY_NAME. */
-
- if(rrec == PERMANENT_TTL)
- ttl = lp_max_ttl();
-
- namerec = add_name_to_subnet( orig_broadcast_subnet, nmbname->name,
- nmbname->name_type, nb_flags, ttl,
- WINS_PROXY_NAME, num_ips, iplist );
-
- if(iplist != &ip)
- SAFE_FREE(iplist);
-
- /*
- * Check that none of the IP addresses we are returning is on the
- * same broadcast subnet as the original requesting packet. If it
- * is then don't reply (although we still need to add the name
- * to the cache) as the actual machine will be replying also
- * and we don't want two replies to a broadcast query.
- */
-
- if(namerec && original_packet->packet.nmb.header.nm_flags.bcast)
- {
- for( i = 0; i < namerec->data.num_ips; i++)
- {
- if( same_net( namerec->data.ip[i],
- orig_broadcast_subnet->myip,
- orig_broadcast_subnet->mask_ip ) )
- {
- DEBUG( 5, ( "wins_proxy_name_query_request_success: name %s is a WINS \
-proxy name and is also on the same subnet (%s) as the requestor. \
-Not replying.\n",
- nmb_namestr(&namerec->name),
- orig_broadcast_subnet->subnet_name ) );
- return;
- }
- }
- }
-
- /* Finally reply to the original name query. */
- reply_netbios_packet(original_packet, /* Packet to reply to. */
- 0, /* Result code. */
- NMB_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- ttl, /* ttl. */
- rrec->rdata, /* data to send. */
- rrec->rdlength); /* data length. */
-}
-
-/****************************************************************************
-Function called when the name lookup failed.
-****************************************************************************/
-
-static void wins_proxy_name_query_request_fail(struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *question_name, int fail_code)
-{
- DEBUG(4,("wins_proxy_name_query_request_fail: WINS server returned error code %d for lookup \
-of name %s.\n", fail_code, nmb_namestr(question_name) ));
-}
-
-/****************************************************************************
-Function to make a deep copy of the userdata we will need when the WINS
-proxy query returns.
-****************************************************************************/
-
-static struct userdata_struct *wins_proxy_userdata_copy_fn(struct userdata_struct *userdata)
-{
- struct packet_struct *p, *copy_of_p;
- struct userdata_struct *new_userdata =
- (struct userdata_struct *)malloc( userdata->userdata_len );
-
- if(new_userdata == NULL)
- return NULL;
-
- new_userdata->copy_fn = userdata->copy_fn;
- new_userdata->free_fn = userdata->free_fn;
- new_userdata->userdata_len = userdata->userdata_len;
-
- /* Copy the subnet_record pointer. */
- memcpy( new_userdata->data, userdata->data, sizeof(struct subnet_record *) );
-
- /* Extract the pointer to the packet struct */
- memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)],
- sizeof(struct packet_struct *) );
-
- /* Do a deep copy of the packet. */
- if((copy_of_p = copy_packet(p)) == NULL)
- {
- SAFE_FREE(new_userdata);
- return NULL;
- }
-
- /* Lock the copy. */
- copy_of_p->locked = True;
-
- memcpy( &new_userdata->data[sizeof(struct subnet_record *)], (char *)&copy_of_p,
- sizeof(struct packet_struct *) );
-
- return new_userdata;
-}
-
-/****************************************************************************
-Function to free the deep copy of the userdata we used when the WINS
-proxy query returned.
-****************************************************************************/
-
-static void wins_proxy_userdata_free_fn(struct userdata_struct *userdata)
-{
- struct packet_struct *p;
-
- /* Extract the pointer to the packet struct */
- memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)],
- sizeof(struct packet_struct *));
-
- /* Unlock the packet. */
- p->locked = False;
-
- free_packet(p);
- ZERO_STRUCTP(userdata);
- SAFE_FREE(userdata);
-}
-
-/****************************************************************************
- Make a WINS query on behalf of a broadcast client name query request.
-****************************************************************************/
-
-void make_wins_proxy_name_query_request( struct subnet_record *subrec,
- struct packet_struct *incoming_packet,
- struct nmb_name *question_name)
-{
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct subrec *) +
- sizeof(struct packet_struct *))/sizeof(long *) + 1];
- struct userdata_struct *userdata = (struct userdata_struct *)ud;
-
- memset(ud, '\0', sizeof(ud));
-
- userdata->copy_fn = wins_proxy_userdata_copy_fn;
- userdata->free_fn = wins_proxy_userdata_free_fn;
- userdata->userdata_len = sizeof(ud);
- memcpy( userdata->data, (char *)&subrec, sizeof(struct subnet_record *));
- memcpy( &userdata->data[sizeof(struct subnet_record *)], (char *)&incoming_packet,
- sizeof(struct packet_struct *));
-
- /* Now use the unicast subnet to query the name with the WINS server. */
- query_name( unicast_subnet, question_name->name, question_name->name_type,
- wins_proxy_name_query_request_success,
- wins_proxy_name_query_request_fail,
- userdata);
-}
diff --git a/source4/nmbd/nmbd_winsserver.c b/source4/nmbd/nmbd_winsserver.c
deleted file mode 100644
index 6d1f654e84..0000000000
--- a/source4/nmbd/nmbd_winsserver.c
+++ /dev/null
@@ -1,2032 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
-
- Copyright (C) Jeremy Allison 1994-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"
-
-#define WINS_LIST "wins.tdb"
-#define WINS_VERSION 1
-
-/****************************************************************************
-change the wins owner address in the record.
-*****************************************************************************/
-static void update_wins_owner(struct name_record *namerec, struct in_addr wins_ip)
-{
- if (namerec==NULL)
- return;
- namerec->data.wins_ip=wins_ip;
-}
-
-/****************************************************************************
-create the wins flags based on the nb flags and the input value.
-*****************************************************************************/
-static void update_wins_flag(struct name_record *namerec, int flags)
-{
- if (namerec==NULL)
- return;
-
- namerec->data.wins_flags=0x0;
-
- /* if it's a group, it can be a normal or a special one */
- if (namerec->data.nb_flags & NB_GROUP) {
- if (namerec->name.name_type==0x1C)
- namerec->data.wins_flags|=WINS_SGROUP;
- else
- if (namerec->data.num_ips>1)
- namerec->data.wins_flags|=WINS_SGROUP;
- else
- namerec->data.wins_flags|=WINS_NGROUP;
- } else {
- /* can be unique or multi-homed */
- if (namerec->data.num_ips>1)
- namerec->data.wins_flags|=WINS_MHOMED;
- else
- namerec->data.wins_flags|=WINS_UNIQUE;
- }
-
- /* the node type are the same bits */
- namerec->data.wins_flags|=namerec->data.nb_flags&NB_NODETYPEMASK;
-
- /* the static bit is elsewhere */
- if (namerec->data.death_time == PERMANENT_TTL)
- namerec->data.wins_flags|=WINS_STATIC;
-
- /* and add the given bits */
- namerec->data.wins_flags|=flags;
-
- DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n",
- namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
-
-}
-
-/****************************************************************************
-return the general ID value and increase it if requested
-*****************************************************************************/
-static void get_global_id_and_update(SMB_BIG_UINT *current_id, BOOL update)
-{
- /*
- * it's kept as a static here, to prevent people from messing
- * with the value directly
- */
-
- static SMB_BIG_UINT general_id = 1;
-
- DEBUG(5,("get_global_id_and_update: updating version ID: %d\n", (int)general_id));
-
- *current_id = general_id;
-
- if (update)
- general_id++;
-}
-
-/****************************************************************************
-possibly call the WINS hook external program when a WINS change is made
-*****************************************************************************/
-static void wins_hook(const char *operation, struct name_record *namerec, int ttl)
-{
- pstring command;
- char *cmd = lp_wins_hook();
- char *p;
- int i;
-
- if (!cmd || !*cmd) return;
-
- for (p=namerec->name.name; *p; p++) {
- if (!(isalnum((int)*p) || strchr_m("._-",*p))) {
- DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
- return;
- }
- }
-
- p = command;
- p += slprintf(p, sizeof(command)-1, "%s %s %s %02x %d",
- cmd,
- operation,
- namerec->name.name,
- namerec->name.name_type,
- ttl);
-
- for (i=0;i<namerec->data.num_ips;i++) {
- p += slprintf(p, sizeof(command) - (p-command) -1, " %s", inet_ntoa(namerec->data.ip[i]));
- }
-
- DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
- smbrun(command, NULL);
-}
-
-
-/****************************************************************************
-Determine if this packet should be allocated to the WINS server.
-*****************************************************************************/
-
-BOOL packet_is_for_wins_server(struct packet_struct *packet)
-{
- struct nmb_packet *nmb = &packet->packet.nmb;
-
- /* Only unicast packets go to a WINS server. */
- if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True))
- {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
- return False;
- }
-
- /* Check for node status requests. */
- if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
- return False;
-
- switch(nmb->header.opcode)
- {
- /*
- * A WINS server issues WACKS, not receives them.
- */
- case NMB_WACK_OPCODE:
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
- return False;
- /*
- * A WINS server only processes registration and
- * release requests, not responses.
- */
- case NMB_NAME_REG_OPCODE:
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
- if(nmb->header.response)
- {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
- return False;
- }
- break;
-
- case NMB_NAME_RELEASE_OPCODE:
- if(nmb->header.response)
- {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
- return False;
- }
- break;
-
- /*
- * Only process unicast name queries with rd = 1.
- */
- case NMB_NAME_QUERY_OPCODE:
- if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired)
- {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
- return False;
- }
- break;
- }
-
- return True;
-}
-
-/****************************************************************************
-Utility function to decide what ttl to give a register/refresh request.
-*****************************************************************************/
-
-static int get_ttl_from_packet(struct nmb_packet *nmb)
-{
- int ttl = nmb->additional->ttl;
-
- if(ttl < lp_min_wins_ttl() )
- ttl = lp_min_wins_ttl();
-
- if(ttl > lp_max_wins_ttl() )
- ttl = lp_max_wins_ttl();
-
- return ttl;
-}
-
-/****************************************************************************
-Load or create the WINS database.
-*****************************************************************************/
-
-BOOL initialise_wins(void)
-{
- time_t time_now = time(NULL);
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf, newkey;
- struct name_record *namerec = NULL;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- DEBUG(2,("initialise_wins: started\n"));
-
- if(!lp_we_are_a_wins_server())
- return True;
-
- add_samba_names_to_subnet(wins_server_subnet);
-
- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return True;
- }
-
- if (tdb_fetch_int32(tdb, INFO_VERSION) != WINS_VERSION) {
- DEBUG(0,("Discarding invalid wins.dat file\n"));
- tdb_close(tdb);
- return True;
- }
-
- for (kbuf = tdb_firstkey(tdb);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
- fstring name_type;
- pstring name, ip_str;
- char *p;
- int type = 0;
- int nb_flags;
- int ttl;
- unsigned int num_ips;
- int high, low;
- struct in_addr wins_ip;
- struct in_addr *ip_list;
- int wins_flags;
- int len,i;
-
- if (strncmp(kbuf.dptr, ENTRY_PREFIX, strlen(ENTRY_PREFIX)) != 0)
- continue;
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- continue;
-
- fstrcpy(name_type, kbuf.dptr+strlen(ENTRY_PREFIX));
-
- pstrcpy(name, name_type);
-
- if((p = strchr(name,'#')) != NULL) {
- *p = 0;
- sscanf(p+1,"%x",&type);
- }
-
- len = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddfddd",
- &nb_flags, &high, &low,
- ip_str, &ttl, &num_ips, &wins_flags);
-
- wins_ip=*interpret_addr2(ip_str);
-
- /* Don't reload replica records */
- if (!ip_equal(wins_ip, our_fake_ip)) {
- SAFE_FREE(dbuf.dptr);
- continue;
- }
-
- /* Don't reload released or tombstoned records */
- if ((wins_flags&WINS_STATE_MASK) != WINS_ACTIVE) {
- SAFE_FREE(dbuf.dptr);
- continue;
- }
-
- /* Allocate the space for the ip_list. */
- if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("initialise_wins: Malloc fail !\n"));
- return False;
- }
-
- for (i = 0; i < num_ips; i++) {
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", ip_str);
- ip_list[i] = *interpret_addr2(ip_str);
- }
-
- /* add all entries that have 60 seconds or more to live */
- if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
- if(ttl != PERMANENT_TTL)
- ttl -= time_now;
-
- DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
-
- namerec=add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
- ttl, REGISTER_NAME, num_ips, ip_list);
- if (namerec!=NULL) {
- update_wins_owner(namerec, wins_ip);
- update_wins_flag(namerec, wins_flags);
- /* we don't reload the ID, on startup we restart at 1 */
- get_global_id_and_update(&namerec->data.id, True);
- }
-
- } else {
- DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
- }
-
- SAFE_FREE(dbuf.dptr);
- SAFE_FREE(ip_list);
- }
-
- tdb_close(tdb);
- DEBUG(2,("initialise_wins: done\n"));
- return True;
-}
-
-/****************************************************************************
-Send a WINS WACK (Wait ACKnowledgement) response.
-**************************************************************************/
-
-static void send_wins_wack_response(int ttl, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- unsigned char rdata[2];
-
- rdata[0] = rdata[1] = 0;
-
- /* Taken from nmblib.c - we need to send back almost
- identical bytes from the requesting packet header. */
-
- rdata[0] = (nmb->header.opcode & 0xF) << 3;
- if (nmb->header.nm_flags.authoritative &&
- nmb->header.response) rdata[0] |= 0x4;
- if (nmb->header.nm_flags.trunc) rdata[0] |= 0x2;
- if (nmb->header.nm_flags.recursion_desired) rdata[0] |= 0x1;
- if (nmb->header.nm_flags.recursion_available &&
- nmb->header.response) rdata[1] |= 0x80;
- if (nmb->header.nm_flags.bcast) rdata[1] |= 0x10;
-
- reply_netbios_packet(p, /* Packet to reply to. */
- 0, /* Result code. */
- NMB_WAIT_ACK, /* nmbd type code. */
- NMB_WACK_OPCODE, /* opcode. */
- ttl, /* ttl. */
- (char *)rdata, /* data to send. */
- 2); /* data length. */
-}
-
-/****************************************************************************
-Send a WINS name registration response.
-**************************************************************************/
-
-static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
-
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- WINS_REG, /* nmbd type code. */
- NMB_NAME_REG_OPCODE, /* opcode. */
- ttl, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
-}
-
-/***********************************************************************
- Deal with a name refresh request to a WINS server.
-************************************************************************/
-
-void wins_process_name_refresh_request(struct subnet_record *subrec,
- struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct name_record *namerec = NULL;
- int ttl = get_ttl_from_packet(nmb);
- struct in_addr from_ip;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast)
- {
- /*
- * We should only get unicast name refresh packets here.
- * Anyone trying to refresh broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_name_refresh_request: broadcast name refresh request \
-received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
-
- DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s \
-IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
-
- /*
- * See if the name already exists.
- */
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /*
- * If this is a refresh request and the name doesn't exist then
- * treat it like a registration request. This allows us to recover
- * from errors (tridge)
- */
-
- if(namerec == NULL)
- {
- DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
-the name does not exist. Treating as registration.\n", nmb_namestr(question) ));
- wins_process_name_registration_request(subrec,p);
- return;
- }
-
- /*
- * if the name is present but not active,
- * simply remove it and treat the request
- * as a registration
- */
- if (namerec != NULL && !WINS_STATE_ACTIVE(namerec))
- {
- DEBUG(5,("wins_process_name_refresh_request: Name (%s) in WINS was \
-not active - removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- wins_process_name_registration_request(subrec,p);
- return;
- }
-
- /*
- * Check that the group bits for the refreshing name and the
- * name in our database match.
- */
-
- if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) )
- {
- DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \
-does not match group bit in WINS for this name.\n", nmb_namestr(question), group ? "True" : "False" ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * For a unique name check that the person refreshing the name is one of the registered IP
- * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c.
- * Just return success for unique 0x1d refreshes. For normal group names update the ttl
- * and return success.
- */
-
- if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip ))
- {
- /*
- * Update the ttl.
- */
- update_name_ttl(namerec, ttl);
-
- /*
- * if the record is a replica:
- * we take ownership and update the version ID.
- */
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- update_wins_owner(namerec, our_fake_ip);
- get_global_id_and_update(&namerec->data.id, True);
- }
-
- send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
- return;
- }
- else if(group)
- {
- /*
- * Normal groups are all registered with an IP address of 255.255.255.255
- * so we can't search for the IP address.
- */
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
- else if(!group && (question->name_type == 0x1d))
- {
- /*
- * Special name type - just pretend the refresh succeeded.
- */
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
- else
- {
- /*
- * Fail the refresh.
- */
-
- DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \
-is IP is not known to the name.\n", nmb_namestr(question), inet_ntoa(from_ip) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-}
-
-/***********************************************************************
- Deal with a name registration request query success to a client that
- owned the name.
-
- We have a locked pointer to the original packet stashed away in the
- userdata pointer. The success here is actually a failure as it means
- the client we queried wants to keep the name, so we must return
- a registration failure to the original requestor.
-************************************************************************/
-
-static void wins_register_query_success(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *question_name,
- struct in_addr ip,
- struct res_rec *answers)
-{
- struct packet_struct *orig_reg_packet;
-
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
-
- DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
-name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
-
- send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
-
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
-}
-
-/***********************************************************************
- Deal with a name registration request query failure to a client that
- owned the name.
-
- We have a locked pointer to the original packet stashed away in the
- userdata pointer. The failure here is actually a success as it means
- the client we queried didn't want to keep the name, so we can remove
- the old name record and then successfully add the new name.
-************************************************************************/
-
-static void wins_register_query_fail(struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *question_name,
- int rcode)
-{
- struct userdata_struct *userdata = rrec->userdata;
- struct packet_struct *orig_reg_packet;
- struct name_record *namerec = NULL;
-
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
-
- /*
- * We want to just add the name, as we now know the original owner
- * didn't want it. But we can't just do that as an arbitary
- * amount of time may have taken place between the name query
- * request and this timeout/error response. So we check that
- * the name still exists and is in the same state - if so
- * we remove it and call wins_process_name_registration_request()
- * as we know it will do the right thing now.
- */
-
- namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
-
- if( (namerec != NULL)
- && (namerec->data.source == REGISTER_NAME)
- && ip_equal(rrec->packet->ip, *namerec->data.ip) )
- {
- remove_name_from_namelist( subrec, namerec);
- namerec = NULL;
- }
-
- if(namerec == NULL)
- wins_process_name_registration_request(subrec, orig_reg_packet);
- else
- DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
-querying for name %s in order to replace it and this reply.\n", nmb_namestr(question_name) ));
-
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
-}
-
-/***********************************************************************
- Deal with a name registration request to a WINS server.
-
- Use the following pseudocode :
-
- registering_group
- |
- |
- +--------name exists
- | |
- | |
- | +--- existing name is group
- | | |
- | | |
- | | +--- add name (return).
- | |
- | |
- | +--- exiting name is unique
- | |
- | |
- | +--- query existing owner (return).
- |
- |
- +--------name doesn't exist
- |
- |
- +--- add name (return).
-
- registering_unique
- |
- |
- +--------name exists
- | |
- | |
- | +--- existing name is group
- | | |
- | | |
- | | +--- fail add (return).
- | |
- | |
- | +--- exiting name is unique
- | |
- | |
- | +--- query existing owner (return).
- |
- |
- +--------name doesn't exist
- |
- |
- +--- add name (return).
-
- As can be seen from the above, the two cases may be collapsed onto each
- other with the exception of the case where the name already exists and
- is a group name. This case we handle with an if statement.
-
-************************************************************************/
-
-void wins_process_name_registration_request(struct subnet_record *subrec,
- struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- int ttl = get_ttl_from_packet(nmb);
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast)
- {
- /*
- * We should only get unicast name registration packets here.
- * Anyone trying to register broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
-received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
-
- DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
-IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
-
- /*
- * See if the name already exists.
- */
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /*
- * if the record exists but NOT in active state,
- * consider it dead.
- */
- if ( (namerec != NULL) && !WINS_STATE_ACTIVE(namerec))
- {
- DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
-not active - removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- }
-
- /*
- * Deal with the case where the name found was a dns entry.
- * Remove it as we now have a NetBIOS client registering the
- * name.
- */
-
- if( (namerec != NULL)
- && ( (namerec->data.source == DNS_NAME)
- || (namerec->data.source == DNSFAIL_NAME) ) )
- {
- DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
-a dns lookup - removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- }
-
- /*
- * Reject if the name exists and is not a REGISTER_NAME.
- * (ie. Don't allow any static names to be overwritten.
- */
-
- if((namerec != NULL) && (namerec->data.source != REGISTER_NAME))
- {
- DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
-to register name %s. Name already exists in WINS with source type %d.\n",
- nmb_namestr(question), namerec->data.source ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * Special policy decisions based on MS documentation.
- * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
- * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
- */
-
- /*
- * A group name is always added as the local broadcast address, except
- * for group names ending in 0x1c.
- * Group names with type 0x1c are registered with individual IP addresses.
- */
-
- if(registering_group_name && (question->name_type != 0x1c))
- from_ip = *interpret_addr2("255.255.255.255");
-
- /*
- * Ignore all attempts to register a unique 0x1d name, although return success.
- */
-
- if(!registering_group_name && (question->name_type == 0x1d))
- {
- DEBUG(3,("wins_process_name_registration_request: Ignoring request \
-to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
-
- /*
- * Next two cases are the 'if statement' mentioned above.
- */
-
- if((namerec != NULL) && NAME_GROUP(namerec))
- {
- if(registering_group_name)
- {
- /*
- * If we are adding a group name, the name exists and is also a group entry just add this
- * IP address to it and update the ttl.
- */
-
- DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
- inet_ntoa(from_ip), nmb_namestr(question) ));
- /*
- * Check the ip address is not already in the group.
- */
- if(!find_ip_in_name_record(namerec, from_ip)) {
- add_ip_to_name_record(namerec, from_ip);
- /* we need to update the record for replication */
- get_global_id_and_update(&namerec->data.id, True);
-
- /*
- * if the record is a replica, we must change
- * the wins owner to us to make the replication updates
- * it on the other wins servers.
- * And when the partner will receive this record,
- * it will update its own record.
- */
-
- update_wins_owner(namerec, our_fake_ip);
-
- }
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
- else
- {
- /*
- * If we are adding a unique name, the name exists in the WINS db
- * and is a group name then reject the registration.
- *
- * explanation: groups have a higher priority than unique names.
- */
-
- DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
-already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
- }
-
- /*
- * From here on down we know that if the name exists in the WINS db it is
- * a unique name, not a group name.
- */
-
- /*
- * If the name exists and is one of our names then check the
- * registering IP address. If it's not one of ours then automatically
- * reject without doing the query - we know we will reject it.
- */
-
- if((namerec != NULL) && (is_myname(namerec->name.name)) )
- {
- if(!ismyip(from_ip))
- {
- DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
-is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
- else
- {
- /*
- * It's one of our names and one of our IP's - update the ttl.
- */
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
- return;
- }
- }
-
- /*
- * If the name exists and it is a unique registration and the registering IP
- * is the same as the (single) already registered IP then just update the ttl.
- *
- * But not if the record is an active replica. IF it's a replica, it means it can be
- * the same client which has moved and not yet expired. So we don't update
- * the ttl in this case and go beyond to do a WACK and query the old client
- */
-
- if( !registering_group_name
- && (namerec != NULL)
- && (namerec->data.num_ips == 1)
- && ip_equal( namerec->data.ip[0], from_ip )
- && ip_equal(namerec->data.wins_ip, our_fake_ip) )
- {
- update_name_ttl( namerec, ttl );
- send_wins_name_registration_response( 0, ttl, p );
- wins_hook("refresh", namerec, ttl);
- return;
- }
-
- /*
- * Finally if the name exists do a query to the registering machine
- * to see if they still claim to have the name.
- */
-
- if( namerec != NULL )
- {
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
- struct userdata_struct *userdata = (struct userdata_struct *)ud;
-
- /*
- * First send a WACK to the registering machine.
- */
-
- send_wins_wack_response(60, p);
-
- /*
- * When the reply comes back we need the original packet.
- * Lock this so it won't be freed and then put it into
- * the userdata structure.
- */
-
- p->locked = True;
-
- userdata = (struct userdata_struct *)ud;
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = sizeof(struct packet_struct *);
- memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
-
- /*
- * Use the new call to send a query directly to an IP address.
- * This sends the query directly to the IP address, and ensures
- * the recursion desired flag is not set (you were right Luke :-).
- * This function should *only* be called from the WINS server
- * code. JRA.
- */
-
- query_name_from_wins_server( *namerec->data.ip,
- question->name,
- question->name_type,
- wins_register_query_success,
- wins_register_query_fail,
- userdata );
- return;
- }
-
- /*
- * Name did not exist - add it.
- */
-
- (void)add_name_to_subnet( subrec, question->name, question->name_type,
- nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
- if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- wins_hook("add", namerec, ttl);
- }
-
- send_wins_name_registration_response(0, ttl, p);
-}
-
-/***********************************************************************
- Deal with a mutihomed name query success to the machine that
- requested the multihomed name registration.
-
- We have a locked pointer to the original packet stashed away in the
- userdata pointer.
-************************************************************************/
-
-static void wins_multihomed_register_query_success(struct subnet_record *subrec,
- struct userdata_struct *userdata,
- struct nmb_name *question_name,
- struct in_addr ip,
- struct res_rec *answers)
-{
- struct packet_struct *orig_reg_packet;
- struct nmb_packet *nmb;
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- int ttl;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
-
- nmb = &orig_reg_packet->packet.nmb;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
- ttl = get_ttl_from_packet(nmb);
-
- /*
- * We want to just add the new IP, as we now know the requesting
- * machine claims to own it. But we can't just do that as an arbitary
- * amount of time may have taken place between the name query
- * request and this response. So we check that
- * the name still exists and is in the same state - if so
- * we just add the extra IP and update the ttl.
- */
-
- namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
-
- if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) )
- {
- DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
-a subsequent IP address.\n", nmb_namestr(question_name) ));
- send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
-
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
-
- return;
- }
-
- if(!find_ip_in_name_record(namerec, from_ip))
- add_ip_to_name_record(namerec, from_ip);
-
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, orig_reg_packet);
- wins_hook("add", namerec, ttl);
-
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
-}
-
-/***********************************************************************
- Deal with a name registration request query failure to a client that
- owned the name.
-
- We have a locked pointer to the original packet stashed away in the
- userdata pointer.
-************************************************************************/
-
-static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
- struct response_record *rrec,
- struct nmb_name *question_name,
- int rcode)
-{
- struct userdata_struct *userdata = rrec->userdata;
- struct packet_struct *orig_reg_packet;
-
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
-
- DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
-query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
- send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
-
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
- return;
-}
-
-/***********************************************************************
- Deal with a multihomed name registration request to a WINS server.
- These cannot be group name registrations.
-***********************************************************************/
-
-void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
- struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- int ttl = get_ttl_from_packet(nmb);
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast)
- {
- /*
- * We should only get unicast name registration packets here.
- * Anyone trying to register broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
-received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
-
- /*
- * Only unique names should be registered multihomed.
- */
-
- if(group)
- {
- DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
-received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
-
- DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
-IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
-
- /*
- * Deal with policy regarding 0x1d names.
- */
-
- if(question->name_type == 0x1d)
- {
- DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
-to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
-
- /*
- * See if the name already exists.
- */
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /*
- * if the record exists but NOT in active state,
- * consider it dead.
- */
- if ((namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
- DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was not active - removing it.\n", nmb_namestr(question)));
- remove_name_from_namelist(subrec, namerec);
- namerec = NULL;
- }
-
- /*
- * Deal with the case where the name found was a dns entry.
- * Remove it as we now have a NetBIOS client registering the
- * name.
- */
-
- if( (namerec != NULL)
- && ( (namerec->data.source == DNS_NAME)
- || (namerec->data.source == DNSFAIL_NAME) ) )
- {
- DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
-- removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec);
- namerec = NULL;
- }
-
- /*
- * Reject if the name exists and is not a REGISTER_NAME.
- * (ie. Don't allow any static names to be overwritten.
- */
-
- if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) )
- {
- DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
-to register name %s. Name already exists in WINS with source type %d.\n",
- nmb_namestr(question), namerec->data.source ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * Reject if the name exists and is a GROUP name and is active.
- */
-
- if((namerec != NULL) && NAME_GROUP(namerec) && WINS_STATE_ACTIVE(namerec))
- {
- DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
-already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * From here on down we know that if the name exists in the WINS db it is
- * a unique name, not a group name.
- */
-
- /*
- * If the name exists and is one of our names then check the
- * registering IP address. If it's not one of ours then automatically
- * reject without doing the query - we know we will reject it.
- */
-
- if((namerec != NULL) && (is_myname(namerec->name.name)) )
- {
- if(!ismyip(from_ip))
- {
- DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
-is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
- else
- {
- /*
- * It's one of our names and one of our IP's. Ensure the IP is in the record and
- * update the ttl. Update the version ID to force replication.
- */
- if(!find_ip_in_name_record(namerec, from_ip)) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
-
- add_ip_to_name_record(namerec, from_ip);
- wins_hook("add", namerec, ttl);
- } else {
- wins_hook("refresh", namerec, ttl);
- }
-
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
- }
-
- /*
- * If the name exists and is active, check if the IP address is already registered
- * to that name. If so then update the ttl and reply success.
- */
-
- if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip) && WINS_STATE_ACTIVE(namerec))
- {
- update_name_ttl(namerec, ttl);
- /*
- * If it's a replica, we need to become the wins owner
- * to force the replication
- */
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- }
-
- send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
- return;
- }
-
- /*
- * If the name exists do a query to the owner
- * to see if they still want the name.
- */
-
- if(namerec != NULL)
- {
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
- struct userdata_struct *userdata = (struct userdata_struct *)ud;
-
- /*
- * First send a WACK to the registering machine.
- */
-
- send_wins_wack_response(60, p);
-
- /*
- * When the reply comes back we need the original packet.
- * Lock this so it won't be freed and then put it into
- * the userdata structure.
- */
-
- p->locked = True;
-
- userdata = (struct userdata_struct *)ud;
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = sizeof(struct packet_struct *);
- memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
-
- /*
- * Use the new call to send a query directly to an IP address.
- * This sends the query directly to the IP address, and ensures
- * the recursion desired flag is not set (you were right Luke :-).
- * This function should *only* be called from the WINS server
- * code. JRA.
- *
- * Note that this packet is sent to the current owner of the name,
- * not the person who sent the packet
- */
-
- query_name_from_wins_server( namerec->data.ip[0],
- question->name,
- question->name_type,
- wins_multihomed_register_query_success,
- wins_multihomed_register_query_fail,
- userdata );
-
- return;
- }
-
- /*
- * Name did not exist - add it.
- */
-
- (void)add_name_to_subnet( subrec, question->name, question->name_type,
- nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
-
- if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- wins_hook("add", namerec, ttl);
- }
-
- send_wins_name_registration_response(0, ttl, p);
-}
-
-/***********************************************************************
- Deal with the special name query for *<1b>.
-***********************************************************************/
-
-static void process_wins_dmb_query_request(struct subnet_record *subrec,
- struct packet_struct *p)
-{
- struct name_record *namerec = NULL;
- char *prdata;
- int num_ips;
-
- /*
- * Go through all the ACTIVE names in the WINS db looking for those
- * ending in <1b>. Use this to calculate the number of IP
- * addresses we need to return.
- */
-
- num_ips = 0;
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) )
- {
- if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b )
- num_ips += namerec->data.num_ips;
- }
-
- if(num_ips == 0)
- {
- /*
- * There are no 0x1b names registered. Return name query fail.
- */
- send_wins_name_query_response(NAM_ERR, p, NULL);
- return;
- }
-
- if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
- {
- DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
- return;
- }
-
- /*
- * Go through all the names again in the WINS db looking for those
- * ending in <1b>. Add their IP addresses into the list we will
- * return.
- */
-
- num_ips = 0;
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) )
- {
- if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b)
- {
- int i;
- for(i = 0; i < namerec->data.num_ips; i++)
- {
- set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
- putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
- num_ips++;
- }
- }
- }
-
- /*
- * Send back the reply containing the IP list.
- */
-
- reply_netbios_packet(p, /* Packet to reply to. */
- 0, /* Result code. */
- WINS_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- lp_min_wins_ttl(), /* ttl. */
- prdata, /* data to send. */
- num_ips*6); /* data length. */
-
- SAFE_FREE(prdata);
-}
-
-/****************************************************************************
-Send a WINS name query response.
-**************************************************************************/
-
-void send_wins_name_query_response(int rcode, struct packet_struct *p,
- struct name_record *namerec)
-{
- char rdata[6];
- char *prdata = rdata;
- int reply_data_len = 0;
- int ttl = 0;
- int i;
-
- memset(rdata,'\0',6);
-
- if(rcode == 0)
- {
- ttl = (namerec->data.death_time != PERMANENT_TTL) ?
- namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
-
- /* Copy all known ip addresses into the return data. */
- /* Optimise for the common case of one IP address so
- we don't need a malloc. */
-
- if( namerec->data.num_ips == 1 )
- prdata = rdata;
- else
- {
- if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
- {
- DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
- return;
- }
- }
-
- for(i = 0; i < namerec->data.num_ips; i++)
- {
- set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
- putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
- }
-
- sort_query_replies(prdata, i, p->ip);
-
- reply_data_len = namerec->data.num_ips * 6;
- }
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- WINS_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- ttl, /* ttl. */
- prdata, /* data to send. */
- reply_data_len); /* data length. */
-
- if(prdata != rdata)
- SAFE_FREE(prdata);
-}
-
-/***********************************************************************
- Deal with a name query.
-***********************************************************************/
-
-void wins_process_name_query_request(struct subnet_record *subrec,
- struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- struct name_record *namerec = NULL;
-
- DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
- nmb_namestr(question), inet_ntoa(p->ip) ));
-
- /*
- * Special name code. If the queried name is *<1b> then search
- * the entire WINS database and return a list of all the IP addresses
- * registered to any <1b> name. This is to allow domain master browsers
- * to discover other domains that may not have a presence on their subnet.
- */
-
- if(strequal( question->name, "*") && (question->name_type == 0x1b))
- {
- process_wins_dmb_query_request( subrec, p);
- return;
- }
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- if(namerec != NULL)
- {
- /*
- * If the name is not anymore in active state then reply not found.
- * it's fair even if we keep it in the cache for days.
- */
- if (!WINS_STATE_ACTIVE(namerec))
- {
- DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
- nmb_namestr(question) ));
- send_wins_name_query_response(NAM_ERR, p, namerec);
- return;
- }
- /*
- * If it's a DNSFAIL_NAME then reply name not found.
- */
-
- if( namerec->data.source == DNSFAIL_NAME )
- {
- DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
- nmb_namestr(question) ));
- send_wins_name_query_response(NAM_ERR, p, namerec);
- return;
- }
-
- /*
- * If the name has expired then reply name not found.
- */
-
- if( (namerec->data.death_time != PERMANENT_TTL)
- && (namerec->data.death_time < p->timestamp) )
- {
- DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
- nmb_namestr(question) ));
- send_wins_name_query_response(NAM_ERR, p, namerec);
- return;
- }
-
- DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
- nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
-
- send_wins_name_query_response(0, p, namerec);
- return;
- }
-
- /*
- * Name not found in WINS - try a dns query if it's a 0x20 name.
- */
-
- if(lp_dns_proxy() &&
- ((question->name_type == 0x20) || question->name_type == 0))
- {
-
- DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
- nmb_namestr(question) ));
-
- queue_dns_query(p, question, &namerec);
- return;
- }
-
- /*
- * Name not found - return error.
- */
-
- send_wins_name_query_response(NAM_ERR, p, NULL);
-}
-
-/****************************************************************************
-Send a WINS name release response.
-**************************************************************************/
-
-static void send_wins_name_release_response(int rcode, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
-
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_REL, /* nmbd type code. */
- NMB_NAME_RELEASE_OPCODE, /* opcode. */
- 0, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
-}
-
-/***********************************************************************
- Deal with a name release.
-***********************************************************************/
-
-void wins_process_name_release_request(struct subnet_record *subrec,
- struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast)
- {
- /*
- * We should only get unicast name registration packets here.
- * Anyone trying to register broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
-received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
-
- DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
-IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
-
- /*
- * Deal with policy regarding 0x1d names.
- */
-
- if(!releasing_group_name && (question->name_type == 0x1d))
- {
- DEBUG(3,("wins_process_name_release_request: Ignoring request \
-to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
- send_wins_name_release_response(0, p);
- return;
- }
-
- /*
- * See if the name already exists.
- */
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- if( (namerec == NULL)
- || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) )
- {
- send_wins_name_release_response(NAM_ERR, p);
- return;
- }
-
- /*
- * Check that the sending machine has permission to release this name.
- * If it's a group name not ending in 0x1c then just say yes and let
- * the group time out.
- */
-
- if(releasing_group_name && (question->name_type != 0x1c))
- {
- send_wins_name_release_response(0, p);
- return;
- }
-
- /*
- * Check that the releasing node is on the list of IP addresses
- * for this name. Disallow the release if not.
- */
-
- if(!find_ip_in_name_record(namerec, from_ip))
- {
- DEBUG(3,("wins_process_name_release_request: Refusing request to \
-release name %s as IP %s is not one of the known IP's for this name.\n",
- nmb_namestr(question), inet_ntoa(from_ip) ));
- send_wins_name_release_response(NAM_ERR, p);
- return;
- }
-
- /*
- * Check if the record is active. IF it's already released
- * or tombstoned, refuse the release.
- */
- if (!WINS_STATE_ACTIVE(namerec)) {
- DEBUG(3,("wins_process_name_release_request: Refusing request to \
-release name %s as this record is not anymore active.\n",
- nmb_namestr(question) ));
- send_wins_name_release_response(NAM_ERR, p);
- return;
- }
-
- /*
- * Check if the record is a 0x1c group
- * and has more then one ip
- * remove only this address.
- */
-
- if(releasing_group_name &&
- (question->name_type == 0x1c) &&
- (namerec->data.num_ips > 1)) {
- remove_ip_from_name_record(namerec, from_ip);
- DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
- inet_ntoa(from_ip),nmb_namestr(question)));
- send_wins_name_release_response(0, p);
- return;
- }
-
- /*
- * Send a release response.
- * Flag the name as released and update the ttl
- */
-
- send_wins_name_release_response(0, p);
-
- namerec->data.wins_flags |= WINS_RELEASED;
- update_name_ttl(namerec, EXTINCTION_INTERVAL);
-
- wins_hook("delete", namerec, 0);
-}
-
-/*******************************************************************
- WINS time dependent processing.
-******************************************************************/
-
-void initiate_wins_processing(time_t t)
-{
- static time_t lasttime = 0;
- struct name_record *namerec;
- struct name_record *next_namerec;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- if (!lasttime)
- lasttime = t;
- if (t - lasttime < 20)
- return;
-
- lasttime = t;
-
- if(!lp_we_are_a_wins_server())
- return;
-
- for( namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
- namerec;
- namerec = next_namerec ) {
- next_namerec = (struct name_record *)ubi_trNext( namerec );
-
- if( (namerec->data.death_time != PERMANENT_TTL)
- && (namerec->data.death_time < t) ) {
-
- if( namerec->data.source == SELF_NAME ) {
- DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF name %s\n",
- wins_server_subnet->subnet_name, nmb_namestr(&namerec->name) ) );
- namerec->data.death_time += 300;
- namerec->subnet->namelist_changed = True;
- continue;
- }
-
- /* handle records, samba is the wins owner */
- if (ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- switch (namerec->data.wins_flags | WINS_STATE_MASK) {
- case WINS_ACTIVE:
- namerec->data.wins_flags&=~WINS_STATE_MASK;
- namerec->data.wins_flags|=WINS_RELEASED;
- namerec->data.death_time = t + EXTINCTION_INTERVAL;
- DEBUG(3,("initiate_wins_processing: expiring %s\n", nmb_namestr(&namerec->name)));
- break;
- case WINS_RELEASED:
- namerec->data.wins_flags&=~WINS_STATE_MASK;
- namerec->data.wins_flags|=WINS_TOMBSTONED;
- namerec->data.death_time = t + EXTINCTION_TIMEOUT;
- get_global_id_and_update(&namerec->data.id, True);
- DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
- break;
- case WINS_TOMBSTONED:
- DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
- remove_name_from_namelist( wins_server_subnet, namerec );
- break;
- }
- } else {
- switch (namerec->data.wins_flags | WINS_STATE_MASK) {
- case WINS_ACTIVE:
- /* that's not as MS says it should be */
- namerec->data.wins_flags&=~WINS_STATE_MASK;
- namerec->data.wins_flags|=WINS_TOMBSTONED;
- namerec->data.death_time = t + EXTINCTION_TIMEOUT;
- DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
- case WINS_TOMBSTONED:
- DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
- remove_name_from_namelist( wins_server_subnet, namerec );
- break;
- case WINS_RELEASED:
- DEBUG(0,("initiate_wins_processing: %s is in released state and\
-we are not the wins owner !\n", nmb_namestr(&namerec->name)));
- break;
- }
- }
-
- }
- }
-
- if(wins_server_subnet->namelist_changed)
- wins_write_database(True);
-
- wins_server_subnet->namelist_changed = False;
-}
-
-/*******************************************************************
- Write out the current WINS database.
-******************************************************************/
-void wins_write_database(BOOL background)
-{
- struct name_record *namerec;
- pstring fname, fnamenew;
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf;
- pstring key, buf;
- int len;
- int num_record=0;
- SMB_BIG_UINT id;
-
- if(!lp_we_are_a_wins_server())
- return;
-
- /* we will do the writing in a child process to ensure that the parent
- doesn't block while this is done */
- if (background) {
- CatchChild();
- if (sys_fork()) {
- return;
- }
- }
-
- slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
- all_string_sub(fname,"//", "/", 0);
- slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
-
- tdb = tdb_open_log(fnamenew, 0, TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0644);
- if (!tdb) {
- DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
- if (background)
- _exit(0);
- return;
- }
-
- DEBUG(3,("wins_write_database: Dump of WINS name list.\n"));
-
- tdb_store_int32(tdb, INFO_VERSION, WINS_VERSION);
-
- for (namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
- namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) ) {
-
- int i;
- struct tm *tm;
-
- DEBUGADD(3,("%-19s ", nmb_namestr(&namerec->name) ));
-
- if( namerec->data.death_time != PERMANENT_TTL ) {
- char *ts, *nl;
-
- tm = localtime(&namerec->data.death_time);
- ts = asctime(tm);
- nl = strrchr_m( ts, '\n' );
- if( NULL != nl )
- *nl = '\0';
-
- DEBUGADD(3,("TTL = %s ", ts ));
- } else
- DEBUGADD(3,("TTL = PERMANENT "));
-
- for (i = 0; i < namerec->data.num_ips; i++)
- DEBUGADD(0,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
-
- DEBUGADD(3,("0x%2x 0x%2x %15s\n", namerec->data.nb_flags, namerec->data.wins_flags, inet_ntoa(namerec->data.wins_ip)));
-
- if( namerec->data.source == REGISTER_NAME ) {
-
- /* store the type in the key to make the name unique */
- slprintf(key, sizeof(key), "%s%s#%02x", ENTRY_PREFIX, namerec->name.name, namerec->name.name_type);
-
- len = tdb_pack(buf, sizeof(buf), "dddfddd",
- (int)namerec->data.nb_flags,
- (int)(namerec->data.id>>32),
- (int)(namerec->data.id&0xffffffff),
- inet_ntoa(namerec->data.wins_ip),
- (int)namerec->data.death_time,
- namerec->data.num_ips,
- namerec->data.wins_flags);
-
- for (i = 0; i < namerec->data.num_ips; i++)
- len += tdb_pack(buf+len, sizeof(buf)-len, "f", inet_ntoa(namerec->data.ip[i]));
-
- kbuf.dsize = strlen(key)+1;
- kbuf.dptr = key;
- dbuf.dsize = len;
- dbuf.dptr = buf;
- if (tdb_store(tdb, kbuf, dbuf, TDB_INSERT) != 0) return;
-
- num_record++;
- }
- }
-
- /* store the number of records */
- tdb_store_int32(tdb, INFO_COUNT, num_record);
-
- /* get and store the last used ID */
- get_global_id_and_update(&id, False);
- tdb_store_int32(tdb, INFO_ID_HIGH, id>>32);
- tdb_store_int32(tdb, INFO_ID_LOW, id&0xffffffff);
-
- tdb_close(tdb);
-
- chmod(fnamenew,0644);
- unlink(fname);
- rename(fnamenew,fname);
-
- if (background)
- _exit(0);
-}
-
-/****************************************************************************
-process a internal Samba message receiving a wins record
-***************************************************************************/
-void nmbd_wins_new_entry(int msg_type, pid_t src, void *buf, size_t len)
-{
- WINS_RECORD *record;
- struct name_record *namerec = NULL;
- struct name_record *new_namerec = NULL;
- struct nmb_name question;
- BOOL overwrite=False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
- int i;
-
- if (buf==NULL)
- return;
-
- record=(WINS_RECORD *)buf;
-
- ZERO_STRUCT(question);
- memcpy(question.name, record->name, 16);
- question.name_type=record->type;
-
- namerec = find_name_on_subnet(wins_server_subnet, &question, FIND_ANY_NAME);
-
- /* record doesn't exist, add it */
- if (namerec == NULL) {
- DEBUG(3,("nmbd_wins_new_entry: adding new replicated record: %s<%02x> for wins server: %s\n",
- record->name, record->type, inet_ntoa(record->wins_ip)));
-
- new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags,
- EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
- if (new_namerec!=NULL) {
- update_wins_owner(new_namerec, record->wins_ip);
- update_wins_flag(new_namerec, record->wins_flags);
- new_namerec->data.id=record->id;
-
- wins_server_subnet->namelist_changed = True;
- }
- }
-
- /* check if we have a conflict */
- if (namerec != NULL) {
- /* both records are UNIQUE */
- if (namerec->data.wins_flags&WINS_UNIQUE && record->wins_flags&WINS_UNIQUE) {
-
- /* the database record is a replica */
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED) {
- if (ip_equal(namerec->data.wins_ip, record->wins_ip))
- overwrite=True;
- } else
- overwrite=True;
- } else {
- /* we are the wins owner of the database record */
- /* the 2 records have the same IP address */
- if (ip_equal(namerec->data.ip[0], record->ip[0])) {
- if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED)
- get_global_id_and_update(&namerec->data.id, True);
- else
- overwrite=True;
-
- } else {
- /* the 2 records have different IP address */
- if (namerec->data.wins_flags&WINS_ACTIVE) {
- if (record->wins_flags&WINS_TOMBSTONED)
- get_global_id_and_update(&namerec->data.id, True);
- if (record->wins_flags&WINS_ACTIVE)
- /* send conflict challenge to the replica node */
- ;
- } else
- overwrite=True;
- }
-
- }
- }
-
- /* the replica is a standard group */
- if (record->wins_flags&WINS_NGROUP || record->wins_flags&WINS_SGROUP) {
- /* if the database record is unique and active force a name release */
- if (namerec->data.wins_flags&WINS_UNIQUE)
- /* send a release name to the unique node */
- ;
- overwrite=True;
-
- }
-
- /* the replica is a special group */
- if (record->wins_flags&WINS_SGROUP && namerec->data.wins_flags&WINS_SGROUP) {
- if (namerec->data.wins_flags&WINS_ACTIVE) {
- for (i=0; i<record->num_ips; i++)
- if(!find_ip_in_name_record(namerec, record->ip[i]))
- add_ip_to_name_record(namerec, record->ip[i]);
- }
- else
- overwrite=True;
- }
-
- /* the replica is a multihomed host */
-
- /* I'm giving up on multi homed. Too much complex to understand */
-
- if (record->wins_flags&WINS_MHOMED) {
- if (! (namerec->data.wins_flags&WINS_ACTIVE)) {
- if ( !(namerec->data.wins_flags&WINS_RELEASED) && !(namerec->data.wins_flags&WINS_NGROUP))
- overwrite=True;
- }
- else {
- if (ip_equal(record->wins_ip, namerec->data.wins_ip))
- overwrite=True;
-
- if (ip_equal(namerec->data.wins_ip, our_fake_ip))
- if (namerec->data.wins_flags&WINS_UNIQUE)
- get_global_id_and_update(&namerec->data.id, True);
-
- }
-
- if (record->wins_flags&WINS_ACTIVE && namerec->data.wins_flags&WINS_ACTIVE)
- if (namerec->data.wins_flags&WINS_UNIQUE ||
- namerec->data.wins_flags&WINS_MHOMED)
- if (ip_equal(record->wins_ip, namerec->data.wins_ip))
- overwrite=True;
-
- }
-
- if (overwrite == False)
- DEBUG(3, ("nmbd_wins_new_entry: conflict in adding record: %s<%02x> from wins server: %s\n",
- record->name, record->type, inet_ntoa(record->wins_ip)));
- else {
- DEBUG(3, ("nmbd_wins_new_entry: replacing record: %s<%02x> from wins server: %s\n",
- record->name, record->type, inet_ntoa(record->wins_ip)));
-
- /* remove the old record and add a new one */
- remove_name_from_namelist( wins_server_subnet, namerec );
- new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags,
- EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
- if (new_namerec!=NULL) {
- update_wins_owner(new_namerec, record->wins_ip);
- update_wins_flag(new_namerec, record->wins_flags);
- new_namerec->data.id=record->id;
-
- wins_server_subnet->namelist_changed = True;
- }
-
- wins_server_subnet->namelist_changed = True;
- }
-
- }
-}
-
-
-
-
-
-
-
-
diff --git a/source4/nmbd/nmbd_workgroupdb.c b/source4/nmbd/nmbd_workgroupdb.c
deleted file mode 100644
index 3e177bceb4..0000000000
--- a/source4/nmbd/nmbd_workgroupdb.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-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"
-
-extern int ClientNMB;
-
-extern uint16 samba_nb_type;
-
-int workgroup_count = 0; /* unique index key: one for each workgroup */
-
-/****************************************************************************
- Add a workgroup into the list.
- **************************************************************************/
-
-static void add_workgroup(struct subnet_record *subrec, struct work_record *work)
-{
- work->subnet = subrec;
- DLIST_ADD(subrec->workgrouplist, work);
- subrec->work_changed = True;
-}
-
-/****************************************************************************
- Create an empty workgroup.
- **************************************************************************/
-
-static struct work_record *create_workgroup(const char *name, int ttl)
-{
- struct work_record *work;
- struct subnet_record *subrec;
- int t = -1;
-
- if((work = (struct work_record *)malloc(sizeof(*work))) == NULL)
- {
- DEBUG(0,("create_workgroup: malloc fail !\n"));
- return NULL;
- }
- memset((char *)work, '\0', sizeof(*work));
-
- StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
- work->serverlist = NULL;
-
- work->RunningElection = False;
- work->ElectionCount = 0;
- work->announce_interval = 0;
- work->needelection = False;
- work->needannounce = True;
- work->lastannounce_time = time(NULL);
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- work->dom_state = DOMAIN_NONE;
- work->log_state = LOGON_NONE;
-
- work->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;
-
- /* Make sure all token representations of workgroups are unique. */
-
- for (subrec = FIRST_SUBNET; subrec && (t == -1);
- subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- struct work_record *w;
- for (w = subrec->workgrouplist; w && t == -1; w = w->next)
- {
- if (strequal(w->work_group, work->work_group))
- t = w->token;
- }
- }
-
- if (t == -1)
- work->token = ++workgroup_count;
- else
- work->token = t;
-
- /* No known local master browser as yet. */
- *work->local_master_browser_name = '\0';
-
- /* No known domain master browser as yet. */
- *work->dmb_name.name = '\0';
- zero_ip(&work->dmb_addr);
-
- /* WfWg uses 01040b01 */
- /* Win95 uses 01041501 */
- /* NTAS uses ???????? */
- work->ElectionCriterion = (MAINTAIN_LIST)|(BROWSER_ELECTION_VERSION<<8);
- work->ElectionCriterion |= (lp_os_level() << 24);
- if (lp_domain_master())
- work->ElectionCriterion |= 0x80;
-
- return work;
-}
-
-/*******************************************************************
- Remove a workgroup.
- ******************************************************************/
-
-static struct work_record *remove_workgroup_from_subnet(struct subnet_record *subrec,
- struct work_record *work)
-{
- struct work_record *ret_work = NULL;
-
- DEBUG(3,("remove_workgroup: Removing workgroup %s\n", work->work_group));
-
- ret_work = work->next;
-
- remove_all_servers(work);
-
- if (!work->serverlist)
- {
- if (work->prev)
- work->prev->next = work->next;
- if (work->next)
- work->next->prev = work->prev;
-
- if (subrec->workgrouplist == work)
- subrec->workgrouplist = work->next;
-
- ZERO_STRUCTP(work);
- SAFE_FREE(work);
- }
-
- subrec->work_changed = True;
-
- return ret_work;
-}
-
-
-/****************************************************************************
- Find a workgroup in the workgroup list of a subnet.
- **************************************************************************/
-
-struct work_record *find_workgroup_on_subnet(struct subnet_record *subrec,
- const char *name)
-{
- struct work_record *ret;
-
- DEBUG(4, ("find_workgroup_on_subnet: workgroup search for %s on subnet %s: ",
- name, subrec->subnet_name));
-
- for (ret = subrec->workgrouplist; ret; ret = ret->next)
- {
- if (!strcmp(ret->work_group,name))
- {
- DEBUGADD(4, ("found.\n"));
- return(ret);
- }
- }
- DEBUGADD(4, ("not found.\n"));
- return NULL;
-}
-
-/****************************************************************************
- Create a workgroup in the workgroup list of the subnet.
- **************************************************************************/
-
-struct work_record *create_workgroup_on_subnet(struct subnet_record *subrec,
- const char *name, int ttl)
-{
- struct work_record *work = NULL;
-
- DEBUG(4,("create_workgroup_on_subnet: creating group %s on subnet %s\n",
- name, subrec->subnet_name));
-
- if ((work = create_workgroup(name, ttl)))
- {
- add_workgroup(subrec, work);
-
- subrec->work_changed = True;
-
- return(work);
- }
-
- return NULL;
-}
-
-/****************************************************************************
- Update a workgroup ttl.
- **************************************************************************/
-
-void update_workgroup_ttl(struct work_record *work, int ttl)
-{
- if(work->death_time != PERMANENT_TTL)
- work->death_time = time(NULL)+(ttl*3);
- work->subnet->work_changed = True;
-}
-
-/****************************************************************************
- Fail function called if we cannot register the WORKGROUP<0> and
- WORKGROUP<1e> names on the net.
-**************************************************************************/
-
-static void fail_register(struct subnet_record *subrec, struct response_record *rrec,
- struct nmb_name *nmbname)
-{
- DEBUG(0,("fail_register: Failed to register name %s on subnet %s.\n",
- nmb_namestr(nmbname), subrec->subnet_name));
-}
-
-/****************************************************************************
- If the workgroup is our primary workgroup, add the required names to it.
-**************************************************************************/
-
-void initiate_myworkgroup_startup(struct subnet_record *subrec, struct work_record *work)
-{
- int i;
-
- if(!strequal(lp_workgroup(), work->work_group))
- return;
-
- /* If this is a broadcast subnet then start elections on it
- if we are so configured. */
-
- if ((subrec != unicast_subnet) && (subrec != remote_broadcast_subnet) &&
- (subrec != wins_server_subnet) && lp_preferred_master() &&
- lp_local_master())
- {
- DEBUG(3, ("initiate_myworkgroup_startup: preferred master startup for \
-workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
- work->needelection = True;
- work->ElectionCriterion |= (1<<3);
- }
-
- /* Register the WORKGROUP<0> and WORKGROUP<1e> names on the network. */
-
- register_name(subrec,lp_workgroup(),0x0,samba_nb_type|NB_GROUP,
- NULL,
- fail_register,NULL);
-
- register_name(subrec,lp_workgroup(),0x1e,samba_nb_type|NB_GROUP,
- NULL,
- fail_register,NULL);
-
- for( i = 0; my_netbios_names(i); i++)
- {
- const char *name = my_netbios_names(i);
- int stype = lp_default_server_announce() | (lp_local_master() ?
- SV_TYPE_POTENTIAL_BROWSER : 0 );
-
- if(!strequal(lp_netbios_name(), name))
- stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER|
- SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
-
- create_server_on_workgroup(work,name,stype|SV_TYPE_LOCAL_LIST_ONLY,
- PERMANENT_TTL,
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
- DEBUG(3,("initiate_myworkgroup_startup: Added server name entry %s \
-on subnet %s\n", name, subrec->subnet_name));
- }
-}
-
-/****************************************************************************
- Dump a copy of the workgroup database into the log file.
- **************************************************************************/
-
-void dump_workgroups(BOOL force_write)
-{
- struct subnet_record *subrec;
- int debuglevel = force_write ? 0 : 4;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- if (subrec->workgrouplist)
- {
- struct work_record *work;
-
- if( DEBUGLVL( debuglevel ) )
- {
- dbgtext( "dump_workgroups()\n " );
- dbgtext( "dump workgroup on subnet %15s: ", subrec->subnet_name );
- dbgtext( "netmask=%15s:\n", inet_ntoa(subrec->mask_ip) );
- }
-
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- DEBUGADD( debuglevel, ( "\t%s(%d) current master browser = %s\n",
- work->work_group,
- work->token,
- *work->local_master_browser_name
- ? work->local_master_browser_name : "UNKNOWN" ) );
- if (work->serverlist)
- {
- struct server_record *servrec;
- for (servrec = work->serverlist; servrec; servrec = servrec->next)
- {
- DEBUGADD( debuglevel, ( "\t\t%s %8x (%s)\n",
- servrec->serv.name,
- servrec->serv.type,
- servrec->serv.comment ) );
- }
- }
- }
- }
- }
-}
-
-/****************************************************************************
- Expire any dead servers on all workgroups. If the workgroup has expired
- remove it.
- **************************************************************************/
-
-void expire_workgroups_and_servers(time_t t)
-{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
- struct work_record *nextwork;
-
- for (work = subrec->workgrouplist; work; work = nextwork)
- {
- nextwork = work->next;
- expire_servers(work, t);
-
- if ((work->serverlist == NULL) && (work->death_time != PERMANENT_TTL) &&
- ((t == -1) || (work->death_time < t)))
- {
- DEBUG(3,("expire_workgroups_and_servers: Removing timed out workgroup %s\n",
- work->work_group));
- remove_workgroup_from_subnet(subrec, work);
- }
- }
- }
-}
diff --git a/source4/nsswitch/README b/source4/nsswitch/README
deleted file mode 100644
index 9f0c581df6..0000000000
--- a/source4/nsswitch/README
+++ /dev/null
@@ -1,13 +0,0 @@
-This extension provides a "wins" module for NSS on glibc2/Linux. This
-allows you to use a WINS entry in /etc/nsswitch.conf for hostname
-resolution, allowing you to resolve netbios names via start unix
-gethostbyname() calls. The end result is that you can use netbios
-names as host names in unix apps.
-
-1) run configure
-2) run "make nsswitch"
-3) cp nsswitch/libnss_wins.so /lib/libnss_wins.so.2
-4) add a wins entry to the hosts line in /etc/nsswitch.conf
-5) use it
-
-tridge@linuxcare.com
diff --git a/source4/nsswitch/config.m4 b/source4/nsswitch/config.m4
deleted file mode 100644
index 2d5efe0eb6..0000000000
--- a/source4/nsswitch/config.m4
+++ /dev/null
@@ -1,105 +0,0 @@
-#################################################
-# Check whether winbind is supported on this platform. If so we need to
-# build and install client programs, sbin programs and shared libraries
-
-AC_MSG_CHECKING(whether to build winbind)
-
-# Initially, the value of $host_os decides whether winbind is supported
-
-case "$host_os" in
- *linux*|*irix*)
- HAVE_WINBIND=yes
- ;;
- *solaris*)
- HAVE_WINBIND=yes
- WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o"
- WINBIND_NSS_EXTRA_LIBS="-lsocket"
- ;;
- *hpux11*)
- HAVE_WINBIND=yes
- WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o"
- ;;
- *)
- HAVE_WINBIND=no
- winbind_no_reason=", unsupported on $host_os"
- ;;
-esac
-
-AC_SUBST(WINBIND_NSS_EXTRA_OBJS)
-AC_SUBST(WINBIND_NSS_EXTRA_LIBS)
-
-# Check the setting of --with-winbindd
-
-AC_ARG_WITH(winbind,
-[ --with-winbind Build winbind (default, if supported by OS)],
-[
- case "$withval" in
- yes)
- HAVE_WINBIND=yes
- ;;
- no)
- HAVE_WINBIND=no
- winbind_reason=""
- ;;
- esac ],
-)
-
-# We need unix domain sockets for winbind
-if test x"$HAVE_WINBIND" = x"yes"; then
- if test x"$samba_cv_unixsocket" = x"no"; then
- winbind_no_reason=", no unix domain socket support on $host_os"
- HAVE_WINBIND=no
- fi
-fi
-
-# Display test results
-
-if test x"$HAVE_WINBIND" = x"yes"; then
- AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_WINBIND,1,[Whether to build winbind])
-
- EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/wbinfo\$(EXEEXT)"
- EXTRA_SBIN_PROGS="$EXTRA_SBIN_PROGS bin/winbindd\$(EXEEXT)"
- if test x"$BLDSHARED" = x"true"; then
- case "$host_os" in
- *irix*)
- SHLIB_PROGS="$SHLIB_PROGS nsswitch/libns_winbind.so"
- ;;
- *)
- SHLIB_PROGS="$SHLIB_PROGS nsswitch/libnss_winbind.so"
- ;;
- esac
- if test x"$with_pam" = x"yes"; then
- SHLIB_PROGS="$SHLIB_PROGS nsswitch/pam_winbind.so"
- fi
- fi
-else
- AC_MSG_RESULT(no$winbind_no_reason)
-fi
-
-# Solaris has some extra fields in struct passwd that need to be
-# initialised otherwise nscd crashes. Unfortunately autoconf < 2.50
-# doesn't have the AC_CHECK_MEMBER macro which would be handy for checking
-# this.
-
-#AC_CHECK_MEMBER(struct passwd.pw_comment,
-# AC_DEFINE(HAVE_PASSWD_PW_COMMENT, 1, [Defined if struct passwd has pw_comment field]),
-# [#include <pwd.h>])
-
-AC_CACHE_CHECK([whether struct passwd has pw_comment],samba_cv_passwd_pw_comment, [
- AC_TRY_COMPILE([#include <pwd.h>],[struct passwd p; p.pw_comment;],
- samba_cv_passwd_pw_comment=yes,samba_cv_passwd_pw_comment=no)])
-if test x"$samba_cv_passwd_pw_comment" = x"yes"; then
- AC_DEFINE(HAVE_PASSWD_PW_COMMENT,1,[Whether struct passwd has pw_comment])
-fi
-
-#AC_CHECK_MEMBER(struct passwd.pw_age,
-# AC_DEFINE(HAVE_PASSWD_PW_AGE, 1, [Defined if struct passwd has pw_age field]),
-# [#include <pwd.h>])
-
-AC_CACHE_CHECK([whether struct passwd has pw_age],samba_cv_passwd_pw_age, [
- AC_TRY_COMPILE([#include <pwd.h>],[struct passwd p; p.pw_age;],
- samba_cv_passwd_pw_age=yes,samba_cv_passwd_pw_age=no)])
-if test x"$samba_cv_passwd_pw_age" = x"yes"; then
- AC_DEFINE(HAVE_PASSWD_PW_AGE,1,[Whether struct passwd has pw_age])
-fi
diff --git a/source4/nsswitch/hp_nss_common.h b/source4/nsswitch/hp_nss_common.h
deleted file mode 100644
index 5bd5374182..0000000000
--- a/source4/nsswitch/hp_nss_common.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _HP_NSS_COMMON_H
-#define _HP_NSS_COMMON_H
-
-/*
- Unix SMB/CIFS implementation.
-
- Donated by HP to enable Winbindd to build on HPUX 11.x.
- Copyright (C) Jeremy Allison 2002.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#ifdef HAVE_SYNCH_H
-#include <synch.h>
-#endif
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-
-typedef enum {
- NSS_SUCCESS,
- NSS_NOTFOUND,
- NSS_UNAVAIL,
- NSS_TRYAGAIN
-} nss_status_t;
-
-struct nss_backend;
-
-typedef nss_status_t (*nss_backend_op_t)(struct nss_backend *, void *args);
-
-struct nss_backend {
- nss_backend_op_t *ops;
- int n_ops;
-};
-typedef struct nss_backend nss_backend_t;
-typedef int nss_dbop_t;
-
-#endif /* _HP_NSS_COMMON_H */
diff --git a/source4/nsswitch/hp_nss_dbdefs.h b/source4/nsswitch/hp_nss_dbdefs.h
deleted file mode 100644
index bd24772e33..0000000000
--- a/source4/nsswitch/hp_nss_dbdefs.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef _HP_NSS_DBDEFS_H
-#define _HP_NSS_DBDEFS_H
-
-/*
- Unix SMB/CIFS implementation.
-
- Donated by HP to enable Winbindd to build on HPUX 11.x.
- Copyright (C) Jeremy Allison 2002.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#include <errno.h>
-#include <netdb.h>
-#include <limits.h>
-
-#ifndef NSS_INCLUDE_UNSAFE
-#define NSS_INCLUDE_UNSAFE 1 /* Build old, MT-unsafe interfaces, */
-#endif /* NSS_INCLUDE_UNSAFE */
-
-enum nss_netgr_argn {
- NSS_NETGR_MACHINE,
- NSS_NETGR_USER,
- NSS_NETGR_DOMAIN,
- NSS_NETGR_N
-};
-
-enum nss_netgr_status {
- NSS_NETGR_FOUND,
- NSS_NETGR_NO,
- NSS_NETGR_NOMEM
-};
-
-typedef unsigned nss_innetgr_argc;
-typedef char **nss_innetgr_argv;
-
-struct nss_innetgr_1arg {
- nss_innetgr_argc argc;
- nss_innetgr_argv argv;
-};
-
-typedef struct {
- void *result; /* "result" parameter to getXbyY_r() */
- char *buffer; /* "buffer" " " */
- int buflen; /* "buflen" " " */
-} nss_XbyY_buf_t;
-
-extern nss_XbyY_buf_t *_nss_XbyY_buf_alloc(int struct_size, int buffer_size);
-extern void _nss_XbyY_buf_free(nss_XbyY_buf_t *);
-
-union nss_XbyY_key {
- uid_t uid;
- gid_t gid;
- const char *name;
- int number;
- struct {
- long net;
- int type;
- } netaddr;
- struct {
- const char *addr;
- int len;
- int type;
- } hostaddr;
- struct {
- union {
- const char *name;
- int port;
- } serv;
- const char *proto;
- } serv;
- void *ether;
-};
-
-typedef struct nss_XbyY_args {
- nss_XbyY_buf_t buf;
- int stayopen;
- /*
- * Support for setXXXent(stayopen)
- * Used only in hosts, protocols,
- * networks, rpc, and services.
- */
- int (*str2ent)(const char *instr, int instr_len, void *ent, char *buffer, int buflen);
- union nss_XbyY_key key;
-
- void *returnval;
- int erange;
- int h_errno;
- nss_status_t status;
-} nss_XbyY_args_t;
-
-#endif /* _NSS_DBDEFS_H */
diff --git a/source4/nsswitch/nss.h b/source4/nsswitch/nss.h
deleted file mode 100644
index d83a5e237e..0000000000
--- a/source4/nsswitch/nss.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef _NSSWITCH_NSS_H
-#define _NSSWITCH_NSS_H
-/*
- Unix SMB/CIFS implementation.
-
- a common place to work out how to define NSS_STATUS on various
- platforms
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#ifdef HAVE_NSS_COMMON_H
-
-/* Sun Solaris */
-
-#include <nss_common.h>
-#include <nss_dbdefs.h>
-#include <nsswitch.h>
-
-typedef nss_status_t NSS_STATUS;
-
-#define NSS_STATUS_SUCCESS NSS_SUCCESS
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
-
-#elif HAVE_NSS_H
-
-/* GNU */
-
-#include <nss.h>
-
-typedef enum nss_status NSS_STATUS;
-
-#elif HAVE_NS_API_H
-
-/* SGI IRIX */
-
-/* following required to prevent warnings of double definition
- * of datum from ns_api.h
-*/
-#ifdef DATUM
-#define _DATUM_DEFINED
-#endif
-
-#include <ns_api.h>
-
-typedef enum
-{
- NSS_STATUS_SUCCESS=NS_SUCCESS,
- NSS_STATUS_NOTFOUND=NS_NOTFOUND,
- NSS_STATUS_UNAVAIL=NS_UNAVAIL,
- NSS_STATUS_TRYAGAIN=NS_TRYAGAIN
-} NSS_STATUS;
-
-#define NSD_MEM_STATIC 0
-#define NSD_MEM_VOLATILE 1
-#define NSD_MEM_DYNAMIC 2
-
-#elif defined(HPUX) && defined(HAVE_NSSWITCH_H)
-/* HP-UX 11 */
-
-#include "nsswitch/hp_nss_common.h"
-#include "nsswitch/hp_nss_dbdefs.h"
-#include <nsswitch.h>
-
-#ifndef _HAVE_TYPEDEF_NSS_STATUS
-#define _HAVE_TYPEDEF_NSS_STATUS
-typedef nss_status_t NSS_STATUS;
-
-#define NSS_STATUS_SUCCESS NSS_SUCCESS
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
-#endif /* HPUX */
-
-#else /* Nothing's defined. Neither gnu nor sun nor hp */
-
-typedef enum
-{
- NSS_STATUS_SUCCESS=0,
- NSS_STATUS_NOTFOUND=1,
- NSS_STATUS_UNAVAIL=2,
- NSS_STATUS_TRYAGAIN=3
-} NSS_STATUS;
-
-#endif
-
-#endif /* _NSSWITCH_NSS_H */
diff --git a/source4/nsswitch/pam_winbind.c b/source4/nsswitch/pam_winbind.c
deleted file mode 100644
index 123f670366..0000000000
--- a/source4/nsswitch/pam_winbind.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/* pam_winbind module
-
- Copyright Andrew Tridgell <tridge@samba.org> 2000
- Copyright Tim Potter <tpot@samba.org> 2000
- Copyright Andrew Bartlett <abartlet@samba.org> 2002
-
- largely based on pam_userdb by Christian Gafton <gafton@redhat.com>
- also contains large slabs of code from pam_unix by Elliot Lee <sopwith@redhat.com>
- (see copyright below for full details)
-*/
-
-#include "pam_winbind.h"
-
-/* data tokens */
-
-#define MAX_PASSWD_TRIES 3
-
-/* some syslogging */
-static void _pam_log(int err, const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- openlog(MODULE_NAME, LOG_CONS|LOG_PID, LOG_AUTH);
- vsyslog(err, format, args);
- va_end(args);
- closelog();
-}
-
-static int _pam_parse(int argc, const char **argv)
-{
- int ctrl;
- /* step through arguments */
- for (ctrl = 0; argc-- > 0; ++argv) {
-
- /* generic options */
-
- if (!strcmp(*argv,"debug"))
- ctrl |= WINBIND_DEBUG_ARG;
- else if (!strcasecmp(*argv, "use_authtok"))
- ctrl |= WINBIND_USE_AUTHTOK_ARG;
- else if (!strcasecmp(*argv, "use_first_pass"))
- ctrl |= WINBIND_USE_FIRST_PASS_ARG;
- else if (!strcasecmp(*argv, "try_first_pass"))
- ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
- else if (!strcasecmp(*argv, "unknown_ok"))
- ctrl |= WINBIND_UNKNOWN_OK_ARG;
- else {
- _pam_log(LOG_ERR, "pam_parse: unknown option; %s", *argv);
- }
- }
-
- return ctrl;
-}
-
-/* --- authentication management functions --- */
-
-/* Attempt a conversation */
-
-static int converse(pam_handle_t *pamh, int nargs,
- struct pam_message **message,
- struct pam_response **response)
-{
- int retval;
- struct pam_conv *conv;
-
- retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv ) ;
- if (retval == PAM_SUCCESS) {
- retval = conv->conv(nargs, (const struct pam_message **)message,
- response, conv->appdata_ptr);
- }
-
- return retval; /* propagate error status */
-}
-
-
-static int _make_remark(pam_handle_t * pamh, int type, const char *text)
-{
- int retval = PAM_SUCCESS;
-
- struct pam_message *pmsg[1], msg[1];
- struct pam_response *resp;
-
- pmsg[0] = &msg[0];
- msg[0].msg = text;
- msg[0].msg_style = type;
-
- resp = NULL;
- retval = converse(pamh, 1, pmsg, &resp);
-
- if (resp) {
- _pam_drop_reply(resp, 1);
- }
- return retval;
-}
-
-static int pam_winbind_request(enum winbindd_cmd req_type,
- struct winbindd_request *request,
- struct winbindd_response *response)
-{
-
- /* Fill in request and send down pipe */
- init_request(request, req_type);
-
- if (write_sock(request, sizeof(*request)) == -1) {
- _pam_log(LOG_ERR, "write to socket failed!");
- close_sock();
- return PAM_SERVICE_ERR;
- }
-
- /* Wait for reply */
- if (read_reply(response) == -1) {
- _pam_log(LOG_ERR, "read from socket failed!");
- close_sock();
- return PAM_SERVICE_ERR;
- }
-
- /* We are done with the socket - close it and avoid mischeif */
- close_sock();
-
- /* Copy reply data from socket */
- if (response->result != WINBINDD_OK) {
- if (response->data.auth.pam_error != PAM_SUCCESS) {
- _pam_log(LOG_ERR, "request failed: %s, PAM error was %d, NT error was %s",
- response->data.auth.error_string,
- response->data.auth.pam_error,
- response->data.auth.nt_status_string);
- return response->data.auth.pam_error;
- } else {
- _pam_log(LOG_ERR, "request failed, but PAM error 0!");
- return PAM_SERVICE_ERR;
- }
- }
-
- return PAM_SUCCESS;
-}
-
-static int pam_winbind_request_log(enum winbindd_cmd req_type,
- struct winbindd_request *request,
- struct winbindd_response *response,
- int ctrl,
- const char *user)
-{
- int retval;
-
- retval = pam_winbind_request(req_type, request, response);
-
- switch (retval) {
- case PAM_AUTH_ERR:
- /* incorrect password */
- _pam_log(LOG_WARNING, "user `%s' denied access (incorrect password)", user);
- return retval;
- case PAM_ACCT_EXPIRED:
- /* account expired */
- _pam_log(LOG_WARNING, "user `%s' account expired", user);
- return retval;
- case PAM_AUTHTOK_EXPIRED:
- /* password expired */
- _pam_log(LOG_WARNING, "user `%s' password expired", user);
- return retval;
- case PAM_NEW_AUTHTOK_REQD:
- /* password expired */
- _pam_log(LOG_WARNING, "user `%s' new password required", user);
- return retval;
- case PAM_USER_UNKNOWN:
- /* the user does not exist */
- if (ctrl & WINBIND_DEBUG_ARG)
- _pam_log(LOG_NOTICE, "user `%s' not found",
- user);
- if (ctrl & WINBIND_UNKNOWN_OK_ARG) {
- return PAM_IGNORE;
- }
- return retval;
- case PAM_SUCCESS:
- if (req_type == WINBINDD_PAM_AUTH) {
- /* Otherwise, the authentication looked good */
- _pam_log(LOG_NOTICE, "user '%s' granted acces", user);
- } else if (req_type == WINBINDD_PAM_CHAUTHTOK) {
- /* Otherwise, the authentication looked good */
- _pam_log(LOG_NOTICE, "user '%s' password changed", user);
- } else {
- /* Otherwise, the authentication looked good */
- _pam_log(LOG_NOTICE, "user '%s' OK", user);
- }
- return retval;
- default:
- /* we don't know anything about this return value */
- _pam_log(LOG_ERR, "internal module error (retval = %d, user = `%s'",
- retval, user);
- return retval;
- }
-}
-
-/* talk to winbindd */
-static int winbind_auth_request(const char *user, const char *pass, int ctrl)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
-
- strncpy(request.data.auth.user, user,
- sizeof(request.data.auth.user)-1);
-
- strncpy(request.data.auth.pass, pass,
- sizeof(request.data.auth.pass)-1);
-
-
- return pam_winbind_request_log(WINBINDD_PAM_AUTH, &request, &response, ctrl, user);
-}
-
-/* talk to winbindd */
-static int winbind_chauthtok_request(const char *user, const char *oldpass,
- const char *newpass, int ctrl)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
-
- if (request.data.chauthtok.user == NULL) return -2;
-
- strncpy(request.data.chauthtok.user, user,
- sizeof(request.data.chauthtok.user) - 1);
-
- if (oldpass != NULL) {
- strncpy(request.data.chauthtok.oldpass, oldpass,
- sizeof(request.data.chauthtok.oldpass) - 1);
- } else {
- request.data.chauthtok.oldpass[0] = '\0';
- }
-
- if (newpass != NULL) {
- strncpy(request.data.chauthtok.newpass, newpass,
- sizeof(request.data.chauthtok.newpass) - 1);
- } else {
- request.data.chauthtok.newpass[0] = '\0';
- }
-
- return pam_winbind_request_log(WINBINDD_PAM_CHAUTHTOK, &request, &response, ctrl, user);
-}
-
-/*
- * Checks if a user has an account
- *
- * return values:
- * 1 = User not found
- * 0 = OK
- * -1 = System error
- */
-static int valid_user(const char *user)
-{
- if (getpwnam(user)) return 0;
- return 1;
-}
-
-static char *_pam_delete(register char *xx)
-{
- _pam_overwrite(xx);
- _pam_drop(xx);
- return NULL;
-}
-
-/*
- * obtain a password from the user
- */
-
-static int _winbind_read_password(pam_handle_t * pamh
- ,unsigned int ctrl
- ,const char *comment
- ,const char *prompt1
- ,const char *prompt2
- ,const char **pass)
-{
- int authtok_flag;
- int retval;
- const char *item;
- char *token;
-
- /*
- * make sure nothing inappropriate gets returned
- */
-
- *pass = token = NULL;
-
- /*
- * which authentication token are we getting?
- */
-
- authtok_flag = on(WINBIND__OLD_PASSWORD, ctrl) ? PAM_OLDAUTHTOK : PAM_AUTHTOK;
-
- /*
- * should we obtain the password from a PAM item ?
- */
-
- if (on(WINBIND_TRY_FIRST_PASS_ARG, ctrl) || on(WINBIND_USE_FIRST_PASS_ARG, ctrl)) {
- retval = pam_get_item(pamh, authtok_flag, (const void **) &item);
- if (retval != PAM_SUCCESS) {
- /* very strange. */
- _pam_log(LOG_ALERT,
- "pam_get_item returned error to unix-read-password"
- );
- return retval;
- } else if (item != NULL) { /* we have a password! */
- *pass = item;
- item = NULL;
- return PAM_SUCCESS;
- } else if (on(WINBIND_USE_FIRST_PASS_ARG, ctrl)) {
- return PAM_AUTHTOK_RECOVER_ERR; /* didn't work */
- } else if (on(WINBIND_USE_AUTHTOK_ARG, ctrl)
- && off(WINBIND__OLD_PASSWORD, ctrl)) {
- return PAM_AUTHTOK_RECOVER_ERR;
- }
- }
- /*
- * getting here implies we will have to get the password from the
- * user directly.
- */
-
- {
- struct pam_message msg[3], *pmsg[3];
- struct pam_response *resp;
- int i, replies;
-
- /* prepare to converse */
-
- if (comment != NULL) {
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_TEXT_INFO;
- msg[0].msg = comment;
- i = 1;
- } else {
- i = 0;
- }
-
- pmsg[i] = &msg[i];
- msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[i++].msg = prompt1;
- replies = 1;
-
- if (prompt2 != NULL) {
- pmsg[i] = &msg[i];
- msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[i++].msg = prompt2;
- ++replies;
- }
- /* so call the conversation expecting i responses */
- resp = NULL;
- retval = converse(pamh, i, pmsg, &resp);
-
- if (resp != NULL) {
-
- /* interpret the response */
-
- if (retval == PAM_SUCCESS) { /* a good conversation */
-
- token = x_strdup(resp[i - replies].resp);
- if (token != NULL) {
- if (replies == 2) {
-
- /* verify that password entered correctly */
- if (!resp[i - 1].resp
- || strcmp(token, resp[i - 1].resp)) {
- _pam_delete(token); /* mistyped */
- retval = PAM_AUTHTOK_RECOVER_ERR;
- _make_remark(pamh ,PAM_ERROR_MSG, MISTYPED_PASS);
- }
- }
- } else {
- _pam_log(LOG_NOTICE
- ,"could not recover authentication token");
- }
-
- }
- /*
- * tidy up the conversation (resp_retcode) is ignored
- * -- what is it for anyway? AGM
- */
-
- _pam_drop_reply(resp, i);
-
- } else {
- retval = (retval == PAM_SUCCESS)
- ? PAM_AUTHTOK_RECOVER_ERR : retval;
- }
- }
-
- if (retval != PAM_SUCCESS) {
- if (on(WINBIND_DEBUG_ARG, ctrl))
- _pam_log(LOG_DEBUG,
- "unable to obtain a password");
- return retval;
- }
- /* 'token' is the entered password */
-
- /* we store this password as an item */
-
- retval = pam_set_item(pamh, authtok_flag, token);
- _pam_delete(token); /* clean it up */
- if (retval != PAM_SUCCESS
- || (retval = pam_get_item(pamh, authtok_flag
- ,(const void **) &item))
- != PAM_SUCCESS) {
-
- _pam_log(LOG_CRIT, "error manipulating password");
- return retval;
-
- }
-
- *pass = item;
- item = NULL; /* break link to password */
-
- return PAM_SUCCESS;
-}
-
-PAM_EXTERN
-int pam_sm_authenticate(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- const char *username;
- const char *password;
- int retval = PAM_AUTH_ERR;
-
- /* parse arguments */
- int ctrl = _pam_parse(argc, argv);
-
- /* Get the username */
- retval = pam_get_user(pamh, &username, NULL);
- if ((retval != PAM_SUCCESS) || (!username)) {
- if (ctrl & WINBIND_DEBUG_ARG)
- _pam_log(LOG_DEBUG,"can not get the username");
- return PAM_SERVICE_ERR;
- }
-
- retval = _winbind_read_password(pamh, ctrl, NULL,
- "Password: ", NULL,
- &password);
-
- if (retval != PAM_SUCCESS) {
- _pam_log(LOG_ERR, "Could not retrieve user's password");
- return PAM_AUTHTOK_ERR;
- }
-
- if (ctrl & WINBIND_DEBUG_ARG) {
-
- /* Let's not give too much away in the log file */
-
-#ifdef DEBUG_PASSWORD
- _pam_log(LOG_INFO, "Verify user `%s' with password `%s'",
- username, password);
-#else
- _pam_log(LOG_INFO, "Verify user `%s'", username);
-#endif
- }
-
- /* Now use the username to look up password */
- return winbind_auth_request(username, password, ctrl);
-}
-
-PAM_EXTERN
-int pam_sm_setcred(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- return PAM_SUCCESS;
-}
-
-/*
- * Account management. We want to verify that the account exists
- * before returning PAM_SUCCESS
- */
-PAM_EXTERN
-int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- const char *username;
- int retval = PAM_USER_UNKNOWN;
-
- /* parse arguments */
- int ctrl = _pam_parse(argc, argv);
-
- /* Get the username */
- retval = pam_get_user(pamh, &username, NULL);
- if ((retval != PAM_SUCCESS) || (!username)) {
- if (ctrl & WINBIND_DEBUG_ARG)
- _pam_log(LOG_DEBUG,"can not get the username");
- return PAM_SERVICE_ERR;
- }
-
- /* Verify the username */
- retval = valid_user(username);
- switch (retval) {
- case -1:
- /* some sort of system error. The log was already printed */
- return PAM_SERVICE_ERR;
- case 1:
- /* the user does not exist */
- if (ctrl & WINBIND_DEBUG_ARG)
- _pam_log(LOG_NOTICE, "user `%s' not found",
- username);
- if (ctrl & WINBIND_UNKNOWN_OK_ARG)
- return PAM_IGNORE;
- return PAM_USER_UNKNOWN;
- case 0:
- /* Otherwise, the authentication looked good */
- _pam_log(LOG_NOTICE, "user '%s' granted acces", username);
- return PAM_SUCCESS;
- default:
- /* we don't know anything about this return value */
- _pam_log(LOG_ERR, "internal module error (retval = %d, user = `%s'",
- retval, username);
- return PAM_SERVICE_ERR;
- }
-
- /* should not be reached */
- return PAM_IGNORE;
-}
-PAM_EXTERN
-int pam_sm_open_session(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- /* parse arguments */
- int ctrl = _pam_parse(argc, argv);
- if (ctrl & WINBIND_DEBUG_ARG)
- _pam_log(LOG_DEBUG,"libpam_winbind:pam_sm_open_session handler");
- return PAM_SUCCESS;
-}
-PAM_EXTERN
-int pam_sm_close_session(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- /* parse arguments */
- int ctrl = _pam_parse(argc, argv);
- if (ctrl & WINBIND_DEBUG_ARG)
- _pam_log(LOG_DEBUG,"libpam_winbind:pam_sm_close_session handler");
- return PAM_SUCCESS;
-}
-
-
-
-PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
- int argc, const char **argv)
-{
- unsigned int lctrl;
- int retval;
- unsigned int ctrl = _pam_parse(argc, argv);
-
- /* <DO NOT free() THESE> */
- const char *user;
- char *pass_old, *pass_new;
- /* </DO NOT free() THESE> */
-
- char *Announce;
-
- int retry = 0;
-
- /*
- * First get the name of a user
- */
- retval = pam_get_user(pamh, &user, "Username: ");
- if (retval == PAM_SUCCESS) {
- if (user == NULL) {
- _pam_log(LOG_ERR, "username was NULL!");
- return PAM_USER_UNKNOWN;
- }
- if (retval == PAM_SUCCESS && on(WINBIND_DEBUG_ARG, ctrl))
- _pam_log(LOG_DEBUG, "username [%s] obtained",
- user);
- } else {
- if (on(WINBIND_DEBUG_ARG, ctrl))
- _pam_log(LOG_DEBUG,
- "password - could not identify user");
- return retval;
- }
-
- /*
- * obtain and verify the current password (OLDAUTHTOK) for
- * the user.
- */
-
- if (flags & PAM_PRELIM_CHECK) {
-
- /* instruct user what is happening */
-#define greeting "Changing password for "
- Announce = (char *) malloc(sizeof(greeting) + strlen(user));
- if (Announce == NULL) {
- _pam_log(LOG_CRIT,
- "password - out of memory");
- return PAM_BUF_ERR;
- }
- (void) strcpy(Announce, greeting);
- (void) strcpy(Announce + sizeof(greeting) - 1, user);
-#undef greeting
-
- lctrl = ctrl | WINBIND__OLD_PASSWORD;
- retval = _winbind_read_password(pamh, lctrl
- ,Announce
- ,"(current) NT password: "
- ,NULL
- ,(const char **) &pass_old);
- free(Announce);
-
- if (retval != PAM_SUCCESS) {
- _pam_log(LOG_NOTICE
- ,"password - (old) token not obtained");
- return retval;
- }
- /* verify that this is the password for this user */
-
- retval = winbind_auth_request(user, pass_old, ctrl);
-
- if (retval != PAM_ACCT_EXPIRED
- && retval != PAM_AUTHTOK_EXPIRED
- && retval != PAM_NEW_AUTHTOK_REQD
- && retval != PAM_SUCCESS) {
- pass_old = NULL;
- return retval;
- }
-
- retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
- pass_old = NULL;
- if (retval != PAM_SUCCESS) {
- _pam_log(LOG_CRIT,
- "failed to set PAM_OLDAUTHTOK");
- }
- } else if (flags & PAM_UPDATE_AUTHTOK) {
-
- /*
- * obtain the proposed password
- */
-
- /*
- * get the old token back.
- */
-
- retval = pam_get_item(pamh, PAM_OLDAUTHTOK
- ,(const void **) &pass_old);
-
- if (retval != PAM_SUCCESS) {
- _pam_log(LOG_NOTICE, "user not authenticated");
- return retval;
- }
-
- lctrl = ctrl;
-
- if (on(WINBIND_USE_AUTHTOK_ARG, lctrl)) {
- ctrl = WINBIND_USE_FIRST_PASS_ARG | lctrl;
- }
- retry = 0;
- retval = PAM_AUTHTOK_ERR;
- while ((retval != PAM_SUCCESS) && (retry++ < MAX_PASSWD_TRIES)) {
- /*
- * use_authtok is to force the use of a previously entered
- * password -- needed for pluggable password strength checking
- */
-
- retval = _winbind_read_password(pamh, lctrl
- ,NULL
- ,"Enter new NT password: "
- ,"Retype new NT password: "
- ,(const char **) &pass_new);
-
- if (retval != PAM_SUCCESS) {
- if (on(WINBIND_DEBUG_ARG, ctrl)) {
- _pam_log(LOG_ALERT
- ,"password - new password not obtained");
- }
- pass_old = NULL;/* tidy up */
- return retval;
- }
-
- /*
- * At this point we know who the user is and what they
- * propose as their new password. Verify that the new
- * password is acceptable.
- */
-
- if (pass_new[0] == '\0') {/* "\0" password = NULL */
- pass_new = NULL;
- }
- }
-
- /*
- * By reaching here we have approved the passwords and must now
- * rebuild the password database file.
- */
-
- retval = winbind_chauthtok_request(user, pass_old, pass_new, ctrl);
- _pam_overwrite(pass_new);
- _pam_overwrite(pass_old);
- pass_old = pass_new = NULL;
- } else {
- retval = PAM_SERVICE_ERR;
- }
-
- return retval;
-}
-
-#ifdef PAM_STATIC
-
-/* static module data */
-
-struct pam_module _pam_winbind_modstruct = {
- MODULE_NAME,
- pam_sm_authenticate,
- pam_sm_setcred,
- pam_sm_acct_mgmt,
- pam_sm_open_session,
- pam_sm_close_session,
- pam_sm_chauthtok
-};
-
-#endif
-
-/*
- * Copyright (c) Andrew Tridgell <tridge@samba.org> 2000
- * Copyright (c) Tim Potter <tpot@samba.org> 2000
- * Copyright (c) Andrew Bartlettt <abartlet@samba.org> 2002
- * Copyright (c) Jan Rêkorajski 1999.
- * Copyright (c) Andrew G. Morgan 1996-8.
- * Copyright (c) Alex O. Yuriev, 1996.
- * Copyright (c) Cristian Gafton 1996.
- * Copyright (C) Elliot Lee <sopwith@redhat.com> 1996, Red Hat Software.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * ALTERNATIVELY, this product may be distributed under the terms of
- * the GNU Public License, in which case the provisions of the GPL are
- * required INSTEAD OF the above restrictions. (This clause is
- * necessary due to a potential bad interaction between the GPL and
- * the restrictions contained in a BSD-style copyright.)
- *
- * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
diff --git a/source4/nsswitch/pam_winbind.h b/source4/nsswitch/pam_winbind.h
deleted file mode 100644
index fae635d806..0000000000
--- a/source4/nsswitch/pam_winbind.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* pam_winbind header file
- (Solaris needs some macros from Linux for common PAM code)
-
- Shirish Kalele 2000
-*/
-
-#ifdef HAVE_FEATURES_H
-#include <features.h>
-#endif
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <syslog.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <config.h>
-
-#define MODULE_NAME "pam_winbind"
-#define PAM_SM_AUTH
-#define PAM_SM_ACCOUNT
-#define PAM_SM_PASSWORD
-
-#if defined(SUNOS5) || defined(SUNOS4) || defined(HPUX)
-
-/* Solaris always uses dynamic pam modules */
-#define PAM_EXTERN extern
-#include <security/pam_appl.h>
-
-#define PAM_AUTHTOK_RECOVER_ERR PAM_AUTHTOK_RECOVERY_ERR
-#endif
-
-#ifdef HAVE_SECURITY_PAM_MODULES_H
-#include <security/pam_modules.h>
-#endif
-
-#ifdef HAVE_SECURITY__PAM_MACROS_H
-#include <security/_pam_macros.h>
-#else
-/* Define required macros from (Linux PAM 0.68) security/_pam_macros.h */
-#define _pam_drop_reply(/* struct pam_response * */ reply, /* int */ replies) \
-do { \
- int reply_i; \
- \
- for (reply_i=0; reply_i<replies; ++reply_i) { \
- if (reply[reply_i].resp) { \
- _pam_overwrite(reply[reply_i].resp); \
- free(reply[reply_i].resp); \
- } \
- } \
- if (reply) \
- free(reply); \
-} while (0)
-
-#define _pam_overwrite(x) \
-do { \
- register char *__xx__; \
- if ((__xx__=(x))) \
- while (*__xx__) \
- *__xx__++ = '\0'; \
-} while (0)
-
-/*
- * Don't just free it, forget it too.
- */
-
-#define _pam_drop(X) SAFE_FREE(X)
-
-#define x_strdup(s) ( (s) ? strdup(s):NULL )
-#endif
-
-#define WINBIND_DEBUG_ARG (1<<0)
-#define WINBIND_USE_AUTHTOK_ARG (1<<1)
-#define WINBIND_UNKNOWN_OK_ARG (1<<2)
-#define WINBIND_TRY_FIRST_PASS_ARG (1<<3)
-#define WINBIND_USE_FIRST_PASS_ARG (1<<4)
-#define WINBIND__OLD_PASSWORD (1<<5)
-
-/*
- * here is the string to inform the user that the new passwords they
- * typed were not the same.
- */
-
-#define MISTYPED_PASS "Sorry, passwords do not match"
-
-#define on(x, y) (x & y)
-#define off(x, y) (!(x & y))
-
-#include "winbind_client.h"
diff --git a/source4/nsswitch/wb_client.c b/source4/nsswitch/wb_client.c
deleted file mode 100644
index 6f4d895839..0000000000
--- a/source4/nsswitch/wb_client.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- winbind client code
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Andrew Tridgell 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#include "includes.h"
-#include "nsswitch/nss.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-NSS_STATUS winbindd_request(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response);
-
-/* Fetch the list of groups a user is a member of from winbindd. This is
- used by winbind_getgroups. */
-
-static int wb_getgroups(const char *user, gid_t **groups)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- int result;
-
- /* Call winbindd */
-
- fstrcpy(request.data.username, user);
-
- ZERO_STRUCT(response);
-
- result = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
-
- if (result == NSS_STATUS_SUCCESS) {
-
- /* Return group list. Don't forget to free the group list
- when finished. */
-
- *groups = (gid_t *)response.extra_data;
- return response.data.num_entries;
- }
-
- return -1;
-}
-
-/* Return a list of groups the user is a member of. This function is
- useful for large systems where inverting the group database would be too
- time consuming. If size is zero, list is not modified and the total
- number of groups for the user is returned. */
-
-int winbind_getgroups(const char *user, int size, gid_t *list)
-{
- gid_t *groups = NULL;
- int result, i;
-
- /*
- * Don't do the lookup if the name has no separator _and_ we are not in
- * 'winbind use default domain' mode.
- */
-
- if (!(strchr(user, *lp_winbind_separator()) || lp_winbind_use_default_domain()))
- return -1;
-
- /* Fetch list of groups */
-
- result = wb_getgroups(user, &groups);
-
- if (size == 0)
- goto done;
-
- if (result > size) {
- result = -1;
- errno = EINVAL; /* This is what getgroups() does */
- goto done;
- }
-
- /* Copy list of groups across */
-
- for (i = 0; i < result; i++) {
- list[i] = groups[i];
- }
-
- done:
- SAFE_FREE(groups);
- return result;
-}
diff --git a/source4/nsswitch/wb_common.c b/source4/nsswitch/wb_common.c
deleted file mode 100644
index 89c751a4ef..0000000000
--- a/source4/nsswitch/wb_common.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- winbind client common code
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Andrew Tridgell 2000
- Copyright (C) Andrew Bartlett 2002
-
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#include "winbind_client.h"
-
-/* Global variables. These are effectively the client state information */
-
-int winbindd_fd = -1; /* fd for winbindd socket */
-
-/* Free a response structure */
-
-void free_response(struct winbindd_response *response)
-{
- /* Free any allocated extra_data */
-
- if (response)
- SAFE_FREE(response->extra_data);
-}
-
-/* Initialise a request structure */
-
-void init_request(struct winbindd_request *request, int request_type)
-{
- request->length = sizeof(struct winbindd_request);
-
- request->cmd = (enum winbindd_cmd)request_type;
- request->pid = getpid();
-
-}
-
-/* Initialise a response structure */
-
-void init_response(struct winbindd_response *response)
-{
- /* Initialise return value */
-
- response->result = WINBINDD_ERROR;
-}
-
-/* Close established socket */
-
-void close_sock(void)
-{
- if (winbindd_fd != -1) {
- close(winbindd_fd);
- winbindd_fd = -1;
- }
-}
-
-/* Make sure socket handle isn't stdin, stdout or stderr */
-#define RECURSION_LIMIT 3
-
-static int make_nonstd_fd_internals(int fd, int limit /* Recursion limiter */)
-{
- int new_fd;
- if (fd >= 0 && fd <= 2) {
-#ifdef F_DUPFD
- if ((new_fd = fcntl(fd, F_DUPFD, 3)) == -1) {
- return -1;
- }
- /* Parinoia */
- if (new_fd < 3) {
- close(new_fd);
- return -1;
- }
- close(fd);
- return new_fd;
-#else
- if (limit <= 0)
- return -1;
-
- new_fd = dup(fd);
- if (new_fd == -1)
- return -1;
-
- /* use the program stack to hold our list of FDs to close */
- new_fd = make_nonstd_fd_internals(new_fd, limit - 1);
- close(fd);
- return new_fd;
-#endif
- }
- return fd;
-}
-
-static int make_safe_fd(int fd)
-{
- int result, flags;
- int new_fd = make_nonstd_fd_internals(fd, RECURSION_LIMIT);
- if (new_fd == -1) {
- close(fd);
- return -1;
- }
- /* Socket should be closed on exec() */
-
-#ifdef FD_CLOEXEC
- result = flags = fcntl(new_fd, F_GETFD, 0);
- if (flags >= 0) {
- flags |= FD_CLOEXEC;
- result = fcntl( new_fd, F_SETFD, flags );
- }
- if (result < 0) {
- close(new_fd);
- return -1;
- }
-#endif
- return new_fd;
-}
-
-/* Connect to winbindd socket */
-
-int winbind_open_pipe_sock(void)
-{
-#ifdef HAVE_UNIXSOCKET
- struct sockaddr_un sunaddr;
- static pid_t our_pid;
- struct stat st;
- pstring path;
- int fd;
-
- if (our_pid != getpid()) {
- close_sock();
- our_pid = getpid();
- }
-
- if (winbindd_fd != -1) {
- return winbindd_fd;
- }
-
- /* Check permissions on unix socket directory */
-
- if (lstat(WINBINDD_SOCKET_DIR, &st) == -1) {
- return -1;
- }
-
- if (!S_ISDIR(st.st_mode) ||
- (st.st_uid != 0 && st.st_uid != geteuid())) {
- return -1;
- }
-
- /* Connect to socket */
-
- strncpy(path, WINBINDD_SOCKET_DIR, sizeof(path) - 1);
- path[sizeof(path) - 1] = '\0';
-
- strncat(path, "/", sizeof(path) - 1);
- path[sizeof(path) - 1] = '\0';
-
- strncat(path, WINBINDD_SOCKET_NAME, sizeof(path) - 1);
- path[sizeof(path) - 1] = '\0';
-
- ZERO_STRUCT(sunaddr);
- sunaddr.sun_family = AF_UNIX;
- strncpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path) - 1);
-
- /* If socket file doesn't exist, don't bother trying to connect
- with retry. This is an attempt to make the system usable when
- the winbindd daemon is not running. */
-
- if (lstat(path, &st) == -1) {
- return -1;
- }
-
- /* Check permissions on unix socket file */
-
- if (!S_ISSOCK(st.st_mode) ||
- (st.st_uid != 0 && st.st_uid != geteuid())) {
- return -1;
- }
-
- /* Connect to socket */
-
- if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
- return -1;
- }
-
- if ((winbindd_fd = make_safe_fd( fd)) == -1) {
- return winbindd_fd;
- }
-
- if (connect(winbindd_fd, (struct sockaddr *)&sunaddr,
- sizeof(sunaddr)) == -1) {
- close_sock();
- return -1;
- }
-
- return winbindd_fd;
-#else
- return -1;
-#endif /* HAVE_UNIXSOCKET */
-}
-
-/* Write data to winbindd socket */
-
-int write_sock(void *buffer, int count)
-{
- int result, nwritten;
-
- /* Open connection to winbind daemon */
-
- restart:
-
- if (winbind_open_pipe_sock() == -1) {
- return -1;
- }
-
- /* Write data to socket */
-
- nwritten = 0;
-
- while(nwritten < count) {
- struct timeval tv;
- fd_set r_fds;
-
- /* Catch pipe close on other end by checking if a read()
- call would not block by calling select(). */
-
- FD_ZERO(&r_fds);
- FD_SET(winbindd_fd, &r_fds);
- ZERO_STRUCT(tv);
-
- if (select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv) == -1) {
- close_sock();
- return -1; /* Select error */
- }
-
- /* Write should be OK if fd not available for reading */
-
- if (!FD_ISSET(winbindd_fd, &r_fds)) {
-
- /* Do the write */
-
- result = write(winbindd_fd,
- (char *)buffer + nwritten,
- count - nwritten);
-
- if ((result == -1) || (result == 0)) {
-
- /* Write failed */
-
- close_sock();
- return -1;
- }
-
- nwritten += result;
-
- } else {
-
- /* Pipe has closed on remote end */
-
- close_sock();
- goto restart;
- }
- }
-
- return nwritten;
-}
-
-/* Read data from winbindd socket */
-
-static int read_sock(void *buffer, int count)
-{
- int result = 0, nread = 0;
-
- /* Read data from socket */
-
- while(nread < count) {
-
- result = read(winbindd_fd, (char *)buffer + nread,
- count - nread);
-
- if ((result == -1) || (result == 0)) {
-
- /* Read failed. I think the only useful thing we
- can do here is just return -1 and fail since the
- transaction has failed half way through. */
-
- close_sock();
- return -1;
- }
-
- nread += result;
- }
-
- return result;
-}
-
-/* Read reply */
-
-int read_reply(struct winbindd_response *response)
-{
- int result1, result2 = 0;
-
- if (!response) {
- return -1;
- }
-
- /* Read fixed length response */
-
- if ((result1 = read_sock(response, sizeof(struct winbindd_response)))
- == -1) {
-
- return -1;
- }
-
- /* We actually send the pointer value of the extra_data field from
- the server. This has no meaning in the client's address space
- so we clear it out. */
-
- response->extra_data = NULL;
-
- /* Read variable length response */
-
- if (response->length > sizeof(struct winbindd_response)) {
- int extra_data_len = response->length -
- sizeof(struct winbindd_response);
-
- /* Mallocate memory for extra data */
-
- if (!(response->extra_data = malloc(extra_data_len))) {
- return -1;
- }
-
- if ((result2 = read_sock(response->extra_data, extra_data_len))
- == -1) {
- free_response(response);
- return -1;
- }
- }
-
- /* Return total amount of data read */
-
- return result1 + result2;
-}
-
-/*
- * send simple types of requests
- */
-
-NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
-{
- struct winbindd_request lrequest;
-
- /* Check for our tricky environment variable */
-
- if (getenv(WINBINDD_DONT_ENV)) {
- return NSS_STATUS_NOTFOUND;
- }
-
- if (!request) {
- ZERO_STRUCT(lrequest);
- request = &lrequest;
- }
-
- /* Fill in request and send down pipe */
-
- init_request(request, req_type);
-
- if (write_sock(request, sizeof(*request)) == -1) {
- return NSS_STATUS_UNAVAIL;
- }
-
- return NSS_STATUS_SUCCESS;
-}
-
-/*
- * Get results from winbindd request
- */
-
-NSS_STATUS winbindd_get_response(struct winbindd_response *response)
-{
- struct winbindd_response lresponse;
-
- if (!response) {
- ZERO_STRUCT(lresponse);
- response = &lresponse;
- }
-
- init_response(response);
-
- /* Wait for reply */
- if (read_reply(response) == -1) {
- return NSS_STATUS_UNAVAIL;
- }
-
- /* Throw away extra data if client didn't request it */
- if (response == &lresponse) {
- free_response(response);
- }
-
- /* Copy reply data from socket */
- if (response->result != WINBINDD_OK) {
- return NSS_STATUS_NOTFOUND;
- }
-
- return NSS_STATUS_SUCCESS;
-}
-
-/* Handle simple types of requests */
-
-NSS_STATUS winbindd_request(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response)
-{
- NSS_STATUS status;
-
- status = winbindd_send_request(req_type, request);
- if (status != NSS_STATUS_SUCCESS)
- return(status);
- return winbindd_get_response(response);
-}
diff --git a/source4/nsswitch/wbinfo.c b/source4/nsswitch/wbinfo.c
deleted file mode 100644
index 68dc178bcd..0000000000
--- a/source4/nsswitch/wbinfo.c
+++ /dev/null
@@ -1,891 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind status program.
-
- Copyright (C) Tim Potter 2000-2002
- Copyright (C) Andrew Bartlett 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-#include "debug.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-extern int winbindd_fd;
-
-static char winbind_separator(void)
-{
- struct winbindd_response response;
- static BOOL got_sep;
- static char sep;
-
- if (got_sep)
- return sep;
-
- ZERO_STRUCT(response);
-
- /* Send off request */
-
- if (winbindd_request(WINBINDD_INFO, NULL, &response) !=
- NSS_STATUS_SUCCESS) {
- d_printf("could not obtain winbind separator!\n");
- /* HACK: (this module should not call lp_ funtions) */
- return *lp_winbind_separator();
- }
-
- sep = response.data.info.winbind_separator;
- got_sep = True;
-
- if (!sep) {
- d_printf("winbind separator was NULL!\n");
- /* HACK: (this module should not call lp_ funtions) */
- sep = *lp_winbind_separator();
- }
-
- return sep;
-}
-
-static const char *get_winbind_domain(void)
-{
- struct winbindd_response response;
- static fstring winbind_domain;
-
- ZERO_STRUCT(response);
-
- /* Send off request */
-
- if (winbindd_request(WINBINDD_DOMAIN_NAME, NULL, &response) !=
- NSS_STATUS_SUCCESS) {
- d_printf("could not obtain winbind domain name!\n");
-
- /* HACK: (this module should not call lp_ funtions) */
- return lp_workgroup();
- }
-
- fstrcpy(winbind_domain, response.data.domain_name);
-
- return winbind_domain;
-
-}
-
-/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
- form DOMAIN/user into a domain and a user */
-
-static BOOL parse_wbinfo_domain_user(const char *domuser, fstring domain,
- fstring user)
-{
-
- char *p = strchr(domuser,winbind_separator());
-
- if (!p) {
- fstrcpy(user, domuser);
- fstrcpy(domain, get_winbind_domain());
- return True;
- }
-
- fstrcpy(user, p+1);
- fstrcpy(domain, domuser);
- domain[PTR_DIFF(p, domuser)] = 0;
- strupper(domain);
-
- return True;
-}
-
-/* List groups a user is a member of */
-
-static BOOL wbinfo_get_usergroups(char *user)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- int i;
-
- ZERO_STRUCT(response);
-
- /* Send request */
-
- fstrcpy(request.data.username, user);
-
- result = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
-
- if (result != NSS_STATUS_SUCCESS)
- return False;
-
- for (i = 0; i < response.data.num_entries; i++)
- d_printf("%d\n", (int)((gid_t *)response.extra_data)[i]);
-
- SAFE_FREE(response.extra_data);
-
- return True;
-}
-
-/* Convert NetBIOS name to IP */
-
-static BOOL wbinfo_wins_byname(char *name)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send request */
-
- fstrcpy(request.data.winsreq, name);
-
- if (winbindd_request(WINBINDD_WINS_BYNAME, &request, &response) !=
- NSS_STATUS_SUCCESS) {
- return False;
- }
-
- /* Display response */
-
- printf("%s\n", response.data.winsresp);
-
- return True;
-}
-
-/* Convert IP to NetBIOS name */
-
-static BOOL wbinfo_wins_byip(char *ip)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send request */
-
- fstrcpy(request.data.winsreq, ip);
-
- if (winbindd_request(WINBINDD_WINS_BYIP, &request, &response) !=
- NSS_STATUS_SUCCESS) {
- return False;
- }
-
- /* Display response */
-
- printf("%s\n", response.data.winsresp);
-
- return True;
-}
-
-/* List trusted domains */
-
-static BOOL wbinfo_list_domains(void)
-{
- struct winbindd_response response;
- fstring name;
-
- ZERO_STRUCT(response);
-
- /* Send request */
-
- if (winbindd_request(WINBINDD_LIST_TRUSTDOM, NULL, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Display response */
-
- if (response.extra_data) {
- const char *extra_data = (char *)response.extra_data;
-
- while(next_token(&extra_data, name, ",", sizeof(fstring)))
- d_printf("%s\n", name);
-
- SAFE_FREE(response.extra_data);
- }
-
- return True;
-}
-
-
-/* show sequence numbers */
-static BOOL wbinfo_show_sequence(void)
-{
- struct winbindd_response response;
-
- ZERO_STRUCT(response);
-
- /* Send request */
-
- if (winbindd_request(WINBINDD_SHOW_SEQUENCE, NULL, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Display response */
-
- if (response.extra_data) {
- char *extra_data = (char *)response.extra_data;
- d_printf("%s", extra_data);
- SAFE_FREE(response.extra_data);
- }
-
- return True;
-}
-
-/* Check trust account password */
-
-static BOOL wbinfo_check_secret(void)
-{
- struct winbindd_response response;
- NSS_STATUS result;
-
- ZERO_STRUCT(response);
-
- result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response);
-
- d_printf("checking the trust secret via RPC calls %s\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
-
- if (result != NSS_STATUS_SUCCESS)
- d_printf("error code was %s (0x%x)\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/* Convert uid to sid */
-
-static BOOL wbinfo_uid_to_sid(uid_t uid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send request */
-
- request.data.uid = uid;
-
- if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Display response */
-
- d_printf("%s\n", response.data.sid.sid);
-
- return True;
-}
-
-/* Convert gid to sid */
-
-static BOOL wbinfo_gid_to_sid(gid_t gid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send request */
-
- request.data.gid = gid;
-
- if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Display response */
-
- d_printf("%s\n", response.data.sid.sid);
-
- return True;
-}
-
-/* Convert sid to uid */
-
-static BOOL wbinfo_sid_to_uid(char *sid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send request */
-
- fstrcpy(request.data.sid, sid);
-
- if (winbindd_request(WINBINDD_SID_TO_UID, &request, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Display response */
-
- d_printf("%d\n", (int)response.data.uid);
-
- return True;
-}
-
-static BOOL wbinfo_sid_to_gid(char *sid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send request */
-
- fstrcpy(request.data.sid, sid);
-
- if (winbindd_request(WINBINDD_SID_TO_GID, &request, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Display response */
-
- d_printf("%d\n", (int)response.data.gid);
-
- return True;
-}
-
-/* Convert sid to string */
-
-static BOOL wbinfo_lookupsid(char *sid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send off request */
-
- fstrcpy(request.data.sid, sid);
-
- if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Display response */
-
- d_printf("%s%c%s %d\n", response.data.name.dom_name,
- winbind_separator(), response.data.name.name,
- response.data.name.type);
-
- return True;
-}
-
-/* Convert string to sid */
-
-static BOOL wbinfo_lookupname(char *name)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- parse_wbinfo_domain_user(name, request.data.name.dom_name,
- request.data.name.name);
-
- if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Display response */
-
- d_printf("%s %d\n", response.data.sid.sid, response.data.sid.type);
-
- return True;
-}
-
-/* Authenticate a user with a plaintext password */
-
-static BOOL wbinfo_auth(char *username)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- char *p;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- p = strchr(username, '%');
-
- if (p) {
- *p = 0;
- fstrcpy(request.data.auth.user, username);
- fstrcpy(request.data.auth.pass, p + 1);
- *p = '%';
- } else
- fstrcpy(request.data.auth.user, username);
-
- result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response);
-
- /* Display response */
-
- d_printf("plaintext password authentication %s\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
-
- if (response.data.auth.nt_status)
- d_printf("error code was %s (0x%x)\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/* Authenticate a user with a challenge/response */
-
-static BOOL wbinfo_auth_crap(char *username)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- fstring name_user;
- fstring name_domain;
- fstring pass;
- char *p;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- p = strchr(username, '%');
-
- if (p) {
- *p = 0;
- fstrcpy(pass, p + 1);
- }
-
- parse_wbinfo_domain_user(username, name_domain, name_user);
-
- fstrcpy(request.data.auth_crap.user, name_user);
-
- fstrcpy(request.data.auth_crap.domain, name_domain);
-
- generate_random_buffer(request.data.auth_crap.chal, 8, False);
-
- SMBencrypt(pass, request.data.auth_crap.chal,
- (uchar *)request.data.auth_crap.lm_resp);
- SMBNTencrypt(pass, request.data.auth_crap.chal,
- (uchar *)request.data.auth_crap.nt_resp);
-
- request.data.auth_crap.lm_resp_len = 24;
- request.data.auth_crap.nt_resp_len = 24;
-
- result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
-
- /* Display response */
-
- d_printf("challenge/response password authentication %s\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
-
- if (response.data.auth.nt_status)
- d_printf("error code was %s (0x%x)\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/* Print domain users */
-
-static BOOL print_domain_users(void)
-{
- struct winbindd_response response;
- const char *extra_data;
- fstring name;
-
- /* Send request to winbind daemon */
-
- ZERO_STRUCT(response);
-
- if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Look through extra data */
-
- if (!response.extra_data)
- return False;
-
- extra_data = (const char *)response.extra_data;
-
- while(next_token(&extra_data, name, ",", sizeof(fstring)))
- d_printf("%s\n", name);
-
- SAFE_FREE(response.extra_data);
-
- return True;
-}
-
-/* Print domain groups */
-
-static BOOL print_domain_groups(void)
-{
- struct winbindd_response response;
- const char *extra_data;
- fstring name;
-
- ZERO_STRUCT(response);
-
- if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Look through extra data */
-
- if (!response.extra_data)
- return False;
-
- extra_data = (const char *)response.extra_data;
-
- while(next_token(&extra_data, name, ",", sizeof(fstring)))
- d_printf("%s\n", name);
-
- SAFE_FREE(response.extra_data);
-
- return True;
-}
-
-/* Set the authorised user for winbindd access in secrets.tdb */
-
-static BOOL wbinfo_set_auth_user(char *username)
-{
- char *password;
- fstring user, domain;
-
- /* Separate into user and password */
-
- parse_wbinfo_domain_user(username, domain, user);
-
- password = strchr(user, '%');
-
- if (password) {
- *password = 0;
- password++;
- } else
- password = "";
-
- /* Store or remove DOMAIN\username%password in secrets.tdb */
-
- secrets_init();
-
- if (user[0]) {
-
- if (!secrets_store(SECRETS_AUTH_USER, user,
- strlen(user) + 1)) {
- d_fprintf(stderr, "error storing username\n");
- return False;
- }
-
- /* We always have a domain name added by the
- parse_wbinfo_domain_user() function. */
-
- if (!secrets_store(SECRETS_AUTH_DOMAIN, domain,
- strlen(domain) + 1)) {
- d_fprintf(stderr, "error storing domain name\n");
- return False;
- }
-
- } else {
- secrets_delete(SECRETS_AUTH_USER);
- secrets_delete(SECRETS_AUTH_DOMAIN);
- }
-
- if (password[0]) {
-
- if (!secrets_store(SECRETS_AUTH_PASSWORD, password,
- strlen(password) + 1)) {
- d_fprintf(stderr, "error storing password\n");
- return False;
- }
-
- } else
- secrets_delete(SECRETS_AUTH_PASSWORD);
-
- return True;
-}
-
-static void wbinfo_get_auth_user(void)
-{
- char *user, *domain, *password;
-
- /* Lift data from secrets file */
-
- secrets_init();
-
- user = secrets_fetch(SECRETS_AUTH_USER, NULL);
- domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
- password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
-
- if (!user && !domain && !password) {
- d_printf("No authorised user configured\n");
- return;
- }
-
- /* Pretty print authorised user info */
-
- d_printf("%s%s%s%s%s\n", domain ? domain : "", domain ? "\\" : "",
- user, password ? "%" : "", password ? password : "");
-
- SAFE_FREE(user);
- SAFE_FREE(domain);
- SAFE_FREE(password);
-}
-
-static BOOL wbinfo_ping(void)
-{
- NSS_STATUS result;
-
- result = winbindd_request(WINBINDD_PING, NULL, NULL);
-
- /* Display response */
-
- d_printf("'ping' to winbindd %s on fd %d\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", winbindd_fd);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/* Main program */
-
-enum {
- OPT_SET_AUTH_USER = 1000,
- OPT_GET_AUTH_USER,
- OPT_SEQUENCE
-};
-
-int main(int argc, char **argv)
-{
- int opt;
-
- poptContext pc;
- static char *string_arg;
- static int int_arg;
- BOOL got_command = False;
- int result = 1;
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
-
- /* longName, shortName, argInfo, argPtr, value, descrip,
- argDesc */
-
- { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users"},
- { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g', "Lists all domain groups" },
- { "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N', "Converts NetBIOS name to IP (WINS)", "NETBIOS-NAME" },
- { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I', "Converts IP address to NetBIOS name (WINS)", "IP" },
- { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n', "Converts name to sid", "NAME" },
- { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's', "Converts sid to name", "SID" },
- { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U', "Converts uid to sid" , "UID" },
- { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" },
- { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" },
- { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid", "SID" },
- { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
- { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" },
- { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "show sequence numbers of all domains" },
- { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" },
- { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
- { "set-auth-user", 'A', POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
- { "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL },
- { "ping", 'p', POPT_ARG_NONE, 0, 'p', "'ping' winbindd to see if it is alive" },
- { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version},
- { 0, 0, 0, 0 }
- };
-
- /* Samba client initialisation */
-
- if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
- d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n",
- dyn_CONFIGFILE, strerror(errno));
- exit(1);
- }
-
- if (!init_names())
- return 1;
-
- load_interfaces();
-
- /* Parse options */
-
- pc = poptGetContext("wbinfo", argc, (const char **)argv, long_options, 0);
-
- /* Parse command line options */
-
- if (argc == 1) {
- poptPrintHelp(pc, stderr, 0);
- return 1;
- }
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- if (got_command) {
- d_fprintf(stderr, "No more than one command may be specified at once.\n");
- exit(1);
- }
- got_command = True;
- }
-
- poptFreeContext(pc);
-
- pc = poptGetContext(NULL, argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'u':
- if (!print_domain_users()) {
- d_printf("Error looking up domain users\n");
- goto done;
- }
- break;
- case 'g':
- if (!print_domain_groups()) {
- d_printf("Error looking up domain groups\n");
- goto done;
- }
- break;
- case 's':
- if (!wbinfo_lookupsid(string_arg)) {
- d_printf("Could not lookup sid %s\n", string_arg);
- goto done;
- }
- break;
- case 'n':
- if (!wbinfo_lookupname(string_arg)) {
- d_printf("Could not lookup name %s\n", string_arg);
- goto done;
- }
- break;
- case 'N':
- if (!wbinfo_wins_byname(string_arg)) {
- d_printf("Could not lookup WINS by name %s\n", string_arg);
- goto done;
- }
- break;
- case 'I':
- if (!wbinfo_wins_byip(string_arg)) {
- d_printf("Could not lookup WINS by IP %s\n", string_arg);
- goto done;
- }
- break;
- case 'U':
- if (!wbinfo_uid_to_sid(int_arg)) {
- d_printf("Could not convert uid %d to sid\n", int_arg);
- goto done;
- }
- break;
- case 'G':
- if (!wbinfo_gid_to_sid(int_arg)) {
- d_printf("Could not convert gid %d to sid\n",
- int_arg);
- goto done;
- }
- break;
- case 'S':
- if (!wbinfo_sid_to_uid(string_arg)) {
- d_printf("Could not convert sid %s to uid\n",
- string_arg);
- goto done;
- }
- break;
- case 'Y':
- if (!wbinfo_sid_to_gid(string_arg)) {
- d_printf("Could not convert sid %s to gid\n",
- string_arg);
- goto done;
- }
- break;
- case 't':
- if (!wbinfo_check_secret()) {
- d_printf("Could not check secret\n");
- goto done;
- }
- break;
- case 'm':
- if (!wbinfo_list_domains()) {
- d_printf("Could not list trusted domains\n");
- goto done;
- }
- break;
- case OPT_SEQUENCE:
- if (!wbinfo_show_sequence()) {
- d_printf("Could not show sequence numbers\n");
- goto done;
- }
- break;
- case 'r':
- if (!wbinfo_get_usergroups(string_arg)) {
- d_printf("Could not get groups for user %s\n",
- string_arg);
- goto done;
- }
- break;
- case 'a': {
- BOOL got_error = False;
-
- if (!wbinfo_auth(string_arg)) {
- d_printf("Could not authenticate user %s with "
- "plaintext password\n", string_arg);
- got_error = True;
- }
-
- if (!wbinfo_auth_crap(string_arg)) {
- d_printf("Could not authenticate user %s with "
- "challenge/response\n", string_arg);
- got_error = True;
- }
-
- if (got_error)
- goto done;
- break;
- }
- case 'p': {
- if (!wbinfo_ping()) {
- d_printf("could not ping winbindd!\n");
- goto done;
- }
- break;
- }
- case OPT_SET_AUTH_USER:
- wbinfo_set_auth_user(string_arg);
- break;
- case OPT_GET_AUTH_USER:
- wbinfo_get_auth_user();
- break;
- default:
- d_fprintf(stderr, "Invalid option\n");
- poptPrintHelp(pc, stderr, 0);
- goto done;
- }
- }
-
- result = 0;
-
- /* Exit code */
-
- done:
- poptFreeContext(pc);
- return result;
-}
diff --git a/source4/nsswitch/winbind_client.h b/source4/nsswitch/winbind_client.h
deleted file mode 100644
index 4de2d57cc7..0000000000
--- a/source4/nsswitch/winbind_client.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "winbind_nss_config.h"
-#include "winbindd_nss.h"
-
-void init_request(struct winbindd_request *req,int rq_type);
-NSS_STATUS winbindd_send_request(int req_type,
- struct winbindd_request *request);
-NSS_STATUS winbindd_get_response(struct winbindd_response *response);
-NSS_STATUS winbindd_request(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response);
-int winbind_open_pipe_sock(void);
-int write_sock(void *buffer, int count);
-int read_reply(struct winbindd_response *response);
-void close_sock(void);
-void free_response(struct winbindd_response *response);
-
diff --git a/source4/nsswitch/winbind_nss.c b/source4/nsswitch/winbind_nss.c
deleted file mode 100644
index 0b4c0ce1d0..0000000000
--- a/source4/nsswitch/winbind_nss.c
+++ /dev/null
@@ -1,1341 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Windows NT Domain nsswitch module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#include "winbind_client.h"
-
-#ifdef HAVE_NS_API_H
-#undef VOLATILE
-
-#include <ns_daemon.h>
-#endif
-
-#define MAX_GETPWENT_USERS 250
-#define MAX_GETGRENT_USERS 250
-
-/* Prototypes from wb_common.c */
-
-extern int winbindd_fd;
-
-
-#ifdef HAVE_NS_API_H
-/* IRIX version */
-
-static int send_next_request(nsd_file_t *, struct winbindd_request *);
-static int do_list(int state, nsd_file_t *rq);
-
-static nsd_file_t *current_rq = NULL;
-static int current_winbind_xid = 0;
-static int next_winbind_xid = 0;
-
-typedef struct winbind_xid {
- int xid;
- nsd_file_t *rq;
- struct winbindd_request *request;
- struct winbind_xid *next;
-} winbind_xid_t;
-
-static winbind_xid_t *winbind_xids = (winbind_xid_t *)0;
-
-static int
-winbind_xid_new(int xid, nsd_file_t *rq, struct winbindd_request *request)
-{
- winbind_xid_t *new;
-
- nsd_logprintf(NSD_LOG_LOW,
- "entering winbind_xid_new xid = %d rq = 0x%x, request = 0x%x\n",
- xid, rq, request);
- new = (winbind_xid_t *)nsd_calloc(1,sizeof(winbind_xid_t));
- if (!new) {
- nsd_logprintf(NSD_LOG_RESOURCE,"winbind_xid_new: failed malloc\n");
- return NSD_ERROR;
- }
-
- new->xid = xid;
- new->rq = rq;
- new->request = request;
- new->next = winbind_xids;
- winbind_xids = new;
-
- return NSD_CONTINUE;
-}
-
-/*
-** This routine will look down the xid list and return the request
-** associated with an xid. We remove the record if it is found.
-*/
-nsd_file_t *
-winbind_xid_lookup(int xid, struct winbindd_request **requestp)
-{
- winbind_xid_t **last, *dx;
- nsd_file_t *result=0;
-
- for (last = &winbind_xids, dx = winbind_xids; dx && (dx->xid != xid);
- last = &dx->next, dx = dx->next);
- if (dx) {
- *last = dx->next;
- result = dx->rq;
- *requestp = dx->request;
- SAFE_FREE(dx);
- }
- nsd_logprintf(NSD_LOG_LOW,
- "entering winbind_xid_lookup xid = %d rq = 0x%x, request = 0x%x\n",
- xid, result, dx->request);
-
- return result;
-}
-
-static int
-winbind_startnext_timeout(nsd_file_t **rqp, nsd_times_t *to)
-{
- nsd_file_t *rq;
- struct winbindd_request *request;
-
- nsd_logprintf(NSD_LOG_MIN, "timeout (winbind startnext)\n");
- rq = to->t_file;
- *rqp = rq;
- nsd_timeout_remove(rq);
- request = to->t_clientdata;
- return(send_next_request(rq, request));
-}
-
-static void
-dequeue_request()
-{
- nsd_file_t *rq;
- struct winbindd_request *request;
-
- /*
- * Check for queued requests
- */
- if (winbind_xids) {
- nsd_logprintf(NSD_LOG_MIN, "timeout (winbind) unqueue xid %d\n",
- current_winbind_xid);
- rq = winbind_xid_lookup(current_winbind_xid++, &request);
- /* cause a timeout on the queued request so we can send it */
- nsd_timeout_new(rq,1,winbind_startnext_timeout,request);
- }
-}
-
-static int
-do_request(nsd_file_t *rq, struct winbindd_request *request)
-{
- if (winbind_xids == NULL) {
- /*
- * No outstanding requests.
- * Send off the request to winbindd
- */
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) sending request\n");
- return(send_next_request(rq, request));
- } else {
- /*
- * Just queue it up for now - previous callout or timout
- * will start it up
- */
- nsd_logprintf(NSD_LOG_MIN,
- "lookup (winbind): queue request xid = %d\n",
- next_winbind_xid);
- return(winbind_xid_new(next_winbind_xid++, rq, request));
- }
-}
-
-static int
-winbind_callback(nsd_file_t **rqp, int fd)
-{
- struct winbindd_response response;
- struct winbindd_pw *pw = &response.data.pw;
- struct winbindd_gr *gr = &response.data.gr;
- nsd_file_t *rq;
- NSS_STATUS status;
- fstring result;
- char *members;
- int i, maxlen;
-
- dequeue_request();
-
- nsd_logprintf(NSD_LOG_MIN, "entering callback (winbind)\n");
-
- rq = current_rq;
- *rqp = rq;
-
- nsd_timeout_remove(rq);
- nsd_callback_remove(fd);
-
- ZERO_STRUCT(response);
- status = winbindd_get_response(&response);
-
- if (status != NSS_STATUS_SUCCESS) {
- /* free any extra data area in response structure */
- free_response(&response);
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) returning not found, status = %d\n",
- status);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
-
- maxlen = sizeof(result) - 1;
-
- switch ((int)rq->f_cmd_data) {
- case WINBINDD_WINS_BYNAME:
- case WINBINDD_WINS_BYIP:
- snprintf(result,maxlen,"%s\n",response.data.winsresp);
- break;
- case WINBINDD_GETPWUID:
- case WINBINDD_GETPWNAM:
- snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s\n",
- pw->pw_name,
- pw->pw_passwd,
- pw->pw_uid,
- pw->pw_gid,
- pw->pw_gecos,
- pw->pw_dir,
- pw->pw_shell);
- break;
- case WINBINDD_GETGRNAM:
- case WINBINDD_GETGRGID:
- if (gr->num_gr_mem && response.extra_data)
- members = response.extra_data;
- else
- members = "";
- snprintf(result,maxlen,"%s:%s:%d:%s\n",
- gr->gr_name, gr->gr_passwd, gr->gr_gid, members);
- break;
- case WINBINDD_SETGRENT:
- case WINBINDD_SETPWENT:
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - SETPWENT/SETGRENT\n");
- free_response(&response);
- return(do_list(1,rq));
- case WINBINDD_GETGRENT:
- case WINBINDD_GETGRLST:
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) - %d GETGRENT responses\n",
- response.data.num_entries);
- if (response.data.num_entries) {
- gr = (struct winbindd_gr *)response.extra_data;
- if (! gr ) {
- nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
- free_response(&response);
- return NSD_ERROR;
- }
- members = (char *)response.extra_data +
- (response.data.num_entries * sizeof(struct winbindd_gr));
- for (i = 0; i < response.data.num_entries; i++) {
- snprintf(result,maxlen,"%s:%s:%d:%s\n",
- gr->gr_name, gr->gr_passwd, gr->gr_gid,
- &members[gr->gr_mem_ofs]);
- nsd_logprintf(NSD_LOG_MIN, " GETGRENT %s\n",result);
- nsd_append_element(rq,NS_SUCCESS,result,strlen(result));
- gr++;
- }
- }
- i = response.data.num_entries;
- free_response(&response);
- if (i < MAX_GETPWENT_USERS)
- return(do_list(2,rq));
- else
- return(do_list(1,rq));
- case WINBINDD_GETPWENT:
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) - %d GETPWENT responses\n",
- response.data.num_entries);
- if (response.data.num_entries) {
- pw = (struct winbindd_pw *)response.extra_data;
- if (! pw ) {
- nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
- free_response(&response);
- return NSD_ERROR;
- }
- for (i = 0; i < response.data.num_entries; i++) {
- snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s",
- pw->pw_name,
- pw->pw_passwd,
- pw->pw_uid,
- pw->pw_gid,
- pw->pw_gecos,
- pw->pw_dir,
- pw->pw_shell);
- nsd_logprintf(NSD_LOG_MIN, " GETPWENT %s\n",result);
- nsd_append_element(rq,NS_SUCCESS,result,strlen(result));
- pw++;
- }
- }
- i = response.data.num_entries;
- free_response(&response);
- if (i < MAX_GETPWENT_USERS)
- return(do_list(2,rq));
- else
- return(do_list(1,rq));
- case WINBINDD_ENDGRENT:
- case WINBINDD_ENDPWENT:
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - ENDPWENT/ENDGRENT\n");
- nsd_append_element(rq,NS_SUCCESS,"\n",1);
- free_response(&response);
- return NSD_NEXT;
- default:
- free_response(&response);
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - no valid command\n");
- return NSD_NEXT;
- }
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) %s\n", result);
- /* free any extra data area in response structure */
- free_response(&response);
- nsd_set_result(rq,NS_SUCCESS,result,strlen(result),VOLATILE);
- return NSD_OK;
-}
-
-static int
-winbind_timeout(nsd_file_t **rqp, nsd_times_t *to)
-{
- nsd_file_t *rq;
-
- dequeue_request();
-
- nsd_logprintf(NSD_LOG_MIN, "timeout (winbind)\n");
-
- rq = to->t_file;
- *rqp = rq;
-
- /* Remove the callback and timeout */
- nsd_callback_remove(winbindd_fd);
- nsd_timeout_remove(rq);
-
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
-}
-
-static int
-send_next_request(nsd_file_t *rq, struct winbindd_request *request)
-{
- NSS_STATUS status;
- long timeout;
-
- timeout = 1000;
-
- nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) %d to = %d\n",
- rq->f_cmd_data, timeout);
- status = winbindd_send_request((int)rq->f_cmd_data,request);
- SAFE_FREE(request);
-
- if (status != NSS_STATUS_SUCCESS) {
- nsd_logprintf(NSD_LOG_MIN,
- "send_next_request (winbind) error status = %d\n",status);
- rq->f_status = status;
- return NSD_NEXT;
- }
-
- current_rq = rq;
-
- /*
- * Set up callback and timeouts
- */
- nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) fd = %d\n",winbindd_fd);
- nsd_callback_new(winbindd_fd,winbind_callback,NSD_READ);
- nsd_timeout_new(rq,timeout,winbind_timeout,(void *)0);
- return NSD_CONTINUE;
-}
-
-int init(void)
-{
- nsd_logprintf(NSD_LOG_MIN, "entering init (winbind)\n");
- return(NSD_OK);
-}
-
-int lookup(nsd_file_t *rq)
-{
- char *map;
- char *key;
- struct winbindd_request *request;
-
- nsd_logprintf(NSD_LOG_MIN, "entering lookup (winbind)\n");
- if (! rq)
- return NSD_ERROR;
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0);
- if (! map || ! key) {
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) table or key not defined\n");
- rq->f_status = NS_BADREQ;
- return NSD_ERROR;
- }
-
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind %s)\n",map);
-
- request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request));
- if (! request) {
- nsd_logprintf(NSD_LOG_RESOURCE,
- "lookup (winbind): failed malloc\n");
- return NSD_ERROR;
- }
-
- if (strcasecmp(map,"passwd.byuid") == 0) {
- request->data.uid = atoi(key);
- rq->f_cmd_data = (void *)WINBINDD_GETPWUID;
- } else if (strcasecmp(map,"passwd.byname") == 0) {
- strncpy(request->data.username, key,
- sizeof(request->data.username) - 1);
- request->data.username[sizeof(request->data.username) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_GETPWNAM;
- } else if (strcasecmp(map,"group.byname") == 0) {
- strncpy(request->data.groupname, key,
- sizeof(request->data.groupname) - 1);
- request->data.groupname[sizeof(request->data.groupname) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_GETGRNAM;
- } else if (strcasecmp(map,"group.bygid") == 0) {
- request->data.gid = atoi(key);
- rq->f_cmd_data = (void *)WINBINDD_GETGRGID;
- } else if (strcasecmp(map,"hosts.byname") == 0) {
- strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1);
- request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_WINS_BYNAME;
- } else if (strcasecmp(map,"hosts.byaddr") == 0) {
- strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1);
- request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_WINS_BYIP;
- } else {
- /*
- * Don't understand this map - just return not found
- */
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) unknown table\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
-
- return(do_request(rq, request));
-}
-
-int list(nsd_file_t *rq)
-{
- char *map;
-
- nsd_logprintf(NSD_LOG_MIN, "entering list (winbind)\n");
- if (! rq)
- return NSD_ERROR;
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- if (! map ) {
- nsd_logprintf(NSD_LOG_MIN, "list (winbind) table not defined\n");
- rq->f_status = NS_BADREQ;
- return NSD_ERROR;
- }
-
- nsd_logprintf(NSD_LOG_MIN, "list (winbind %s)\n",map);
-
- return (do_list(0,rq));
-}
-
-static int
-do_list(int state, nsd_file_t *rq)
-{
- char *map;
- struct winbindd_request *request;
-
- nsd_logprintf(NSD_LOG_MIN, "entering do_list (winbind) state = %d\n",state);
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request));
- if (! request) {
- nsd_logprintf(NSD_LOG_RESOURCE,
- "do_list (winbind): failed malloc\n");
- return NSD_ERROR;
- }
-
- if (strcasecmp(map,"passwd.byname") == 0) {
- switch (state) {
- case 0:
- rq->f_cmd_data = (void *)WINBINDD_SETPWENT;
- break;
- case 1:
- request->data.num_entries = MAX_GETPWENT_USERS;
- rq->f_cmd_data = (void *)WINBINDD_GETPWENT;
- break;
- case 2:
- rq->f_cmd_data = (void *)WINBINDD_ENDPWENT;
- break;
- default:
- nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
- } else if (strcasecmp(map,"group.byname") == 0) {
- switch (state) {
- case 0:
- rq->f_cmd_data = (void *)WINBINDD_SETGRENT;
- break;
- case 1:
- request->data.num_entries = MAX_GETGRENT_USERS;
- rq->f_cmd_data = (void *)WINBINDD_GETGRENT;
- break;
- case 2:
- rq->f_cmd_data = (void *)WINBINDD_ENDGRENT;
- break;
- default:
- nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
- } else {
- /*
- * Don't understand this map - just return not found
- */
- nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown table\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
-
- return(do_request(rq, request));
-}
-
-#else
-
-/* Allocate some space from the nss static buffer. The buffer and buflen
- are the pointers passed in by the C library to the _nss_ntdom_*
- functions. */
-
-static char *get_static(char **buffer, int *buflen, int len)
-{
- char *result;
-
- /* Error check. We return false if things aren't set up right, or
- there isn't enough buffer space left. */
-
- if ((buffer == NULL) || (buflen == NULL) || (*buflen < len)) {
- return NULL;
- }
-
- /* Return an index into the static buffer */
-
- result = *buffer;
- *buffer += len;
- *buflen -= len;
-
- return result;
-}
-
-/* I've copied the strtok() replacement function next_token() from
- lib/util_str.c as I really don't want to have to link in any other
- objects if I can possibly avoid it. */
-
-BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
-{
- char *s;
- BOOL quoted;
- size_t len=1;
-
- if (!ptr) return(False);
-
- s = *ptr;
-
- /* default to simple separators */
- if (!sep) sep = " \t\n\r";
-
- /* find the first non sep char */
- while (*s && strchr(sep,*s)) s++;
-
- /* nothing left? */
- if (! *s) return(False);
-
- /* copy over the token */
- for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) {
- if (*s == '\"') {
- quoted = !quoted;
- } else {
- len++;
- *buff++ = *s;
- }
- }
-
- *ptr = (*s) ? s+1 : s;
- *buff = 0;
-
- return(True);
-}
-
-
-/* Fill a pwent structure from a winbindd_response structure. We use
- the static data passed to us by libc to put strings and stuff in.
- Return NSS_STATUS_TRYAGAIN if we run out of memory. */
-
-static NSS_STATUS fill_pwent(struct passwd *result,
- struct winbindd_pw *pw,
- char **buffer, size_t *buflen)
-{
- /* User name */
-
- if ((result->pw_name =
- get_static(buffer, buflen, strlen(pw->pw_name) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->pw_name, pw->pw_name);
-
- /* Password */
-
- if ((result->pw_passwd =
- get_static(buffer, buflen, strlen(pw->pw_passwd) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->pw_passwd, pw->pw_passwd);
-
- /* [ug]id */
-
- result->pw_uid = pw->pw_uid;
- result->pw_gid = pw->pw_gid;
-
- /* GECOS */
-
- if ((result->pw_gecos =
- get_static(buffer, buflen, strlen(pw->pw_gecos) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->pw_gecos, pw->pw_gecos);
-
- /* Home directory */
-
- if ((result->pw_dir =
- get_static(buffer, buflen, strlen(pw->pw_dir) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->pw_dir, pw->pw_dir);
-
- /* Logon shell */
-
- if ((result->pw_shell =
- get_static(buffer, buflen, strlen(pw->pw_shell) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->pw_shell, pw->pw_shell);
-
- /* The struct passwd for Solaris has some extra fields which must
- be initialised or nscd crashes. */
-
-#if HAVE_PASSWD_PW_COMMENT
- result->pw_comment = "";
-#endif
-
-#if HAVE_PASSWD_PW_AGE
- result->pw_age = "";
-#endif
-
- return NSS_STATUS_SUCCESS;
-}
-
-/* Fill a grent structure from a winbindd_response structure. We use
- the static data passed to us by libc to put strings and stuff in.
- Return NSS_STATUS_TRYAGAIN if we run out of memory. */
-
-static NSS_STATUS fill_grent(struct group *result, struct winbindd_gr *gr,
- char *gr_mem, char **buffer, size_t *buflen)
-{
- fstring name;
- int i;
- char *tst;
-
- /* Group name */
-
- if ((result->gr_name =
- get_static(buffer, buflen, strlen(gr->gr_name) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->gr_name, gr->gr_name);
-
- /* Password */
-
- if ((result->gr_passwd =
- get_static(buffer, buflen, strlen(gr->gr_passwd) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->gr_passwd, gr->gr_passwd);
-
- /* gid */
-
- result->gr_gid = gr->gr_gid;
-
- /* Group membership */
-
- if ((gr->num_gr_mem < 0) || !gr_mem) {
- gr->num_gr_mem = 0;
- }
-
- /* this next value is a pointer to a pointer so let's align it */
-
- /* Calculate number of extra bytes needed to align on pointer size boundry */
- if ((i = (unsigned long)(*buffer) % sizeof(char*)) != 0)
- i = sizeof(char*) - i;
-
- if ((tst = get_static(buffer, buflen, ((gr->num_gr_mem + 1) *
- sizeof(char *)+i))) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
- result->gr_mem = (char **)(tst + i);
-
- if (gr->num_gr_mem == 0) {
-
- /* Group is empty */
-
- *(result->gr_mem) = NULL;
- return NSS_STATUS_SUCCESS;
- }
-
- /* Start looking at extra data */
-
- i = 0;
-
- while(next_token((char **)&gr_mem, name, ",", sizeof(fstring))) {
-
- /* Allocate space for member */
-
- if (((result->gr_mem)[i] =
- get_static(buffer, buflen, strlen(name) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy((result->gr_mem)[i], name);
- i++;
- }
-
- /* Terminate list */
-
- (result->gr_mem)[i] = NULL;
-
- return NSS_STATUS_SUCCESS;
-}
-
-/*
- * NSS user functions
- */
-
-static struct winbindd_response getpwent_response;
-
-static int ndx_pw_cache; /* Current index into pwd cache */
-static int num_pw_cache; /* Current size of pwd cache */
-
-/* Rewind "file pointer" to start of ntdom password database */
-
-NSS_STATUS
-_nss_winbind_setpwent(void)
-{
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: setpwent\n", getpid());
-#endif
-
- if (num_pw_cache > 0) {
- ndx_pw_cache = num_pw_cache = 0;
- free_response(&getpwent_response);
- }
-
- return winbindd_request(WINBINDD_SETPWENT, NULL, NULL);
-}
-
-/* Close ntdom password database "file pointer" */
-
-NSS_STATUS
-_nss_winbind_endpwent(void)
-{
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: endpwent\n", getpid());
-#endif
-
- if (num_pw_cache > 0) {
- ndx_pw_cache = num_pw_cache = 0;
- free_response(&getpwent_response);
- }
-
- return winbindd_request(WINBINDD_ENDPWENT, NULL, NULL);
-}
-
-/* Fetch the next password entry from ntdom password database */
-
-NSS_STATUS
-_nss_winbind_getpwent_r(struct passwd *result, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_request request;
- static int called_again;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getpwent\n", getpid());
-#endif
-
- /* Return an entry from the cache if we have one, or if we are
- called again because we exceeded our static buffer. */
-
- if ((ndx_pw_cache < num_pw_cache) || called_again) {
- goto return_result;
- }
-
- /* Else call winbindd to get a bunch of entries */
-
- if (num_pw_cache > 0) {
- free_response(&getpwent_response);
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(getpwent_response);
-
- request.data.num_entries = MAX_GETPWENT_USERS;
-
- ret = winbindd_request(WINBINDD_GETPWENT, &request,
- &getpwent_response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- struct winbindd_pw *pw_cache;
-
- /* Fill cache */
-
- ndx_pw_cache = 0;
- num_pw_cache = getpwent_response.data.num_entries;
-
- /* Return a result */
-
- return_result:
-
- pw_cache = getpwent_response.extra_data;
-
- /* Check data is valid */
-
- if (pw_cache == NULL) {
- return NSS_STATUS_NOTFOUND;
- }
-
- ret = fill_pwent(result, &pw_cache[ndx_pw_cache],
- &buffer, &buflen);
-
- /* Out of memory - try again */
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- called_again = True;
- *errnop = errno = ERANGE;
- return ret;
- }
-
- *errnop = errno = 0;
- called_again = False;
- ndx_pw_cache++;
-
- /* If we've finished with this lot of results free cache */
-
- if (ndx_pw_cache == num_pw_cache) {
- ndx_pw_cache = num_pw_cache = 0;
- free_response(&getpwent_response);
- }
- }
-
- return ret;
-}
-
-/* Return passwd struct from uid */
-
-NSS_STATUS
-_nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- static struct winbindd_response response;
- struct winbindd_request request;
- static int keep_response=0;
-
- /* If our static buffer needs to be expanded we are called again */
- if (!keep_response) {
-
- /* Call for the first time */
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- request.data.uid = uid;
-
- ret = winbindd_request(WINBINDD_GETPWUID, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- ret = fill_pwent(result, &response.data.pw,
- &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = True;
- *errnop = errno = ERANGE;
- return ret;
- }
- }
-
- } else {
-
- /* We've been called again */
-
- ret = fill_pwent(result, &response.data.pw, &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = True;
- *errnop = errno = ERANGE;
- return ret;
- }
-
- keep_response = False;
- *errnop = errno = 0;
- }
-
- free_response(&response);
- return ret;
-}
-
-/* Return passwd struct from username */
-
-NSS_STATUS
-_nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- static struct winbindd_response response;
- struct winbindd_request request;
- static int keep_response;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getpwnam %s\n", getpid(), name);
-#endif
-
- /* If our static buffer needs to be expanded we are called again */
-
- if (!keep_response) {
-
- /* Call for the first time */
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- strncpy(request.data.username, name,
- sizeof(request.data.username) - 1);
- request.data.username
- [sizeof(request.data.username) - 1] = '\0';
-
- ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- ret = fill_pwent(result, &response.data.pw, &buffer,
- &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = True;
- *errnop = errno = ERANGE;
- return ret;
- }
- }
-
- } else {
-
- /* We've been called again */
-
- ret = fill_pwent(result, &response.data.pw, &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = True;
- *errnop = errno = ERANGE;
- return ret;
- }
-
- keep_response = False;
- *errnop = errno = 0;
- }
-
- free_response(&response);
- return ret;
-}
-
-/*
- * NSS group functions
- */
-
-static struct winbindd_response getgrent_response;
-
-static int ndx_gr_cache; /* Current index into grp cache */
-static int num_gr_cache; /* Current size of grp cache */
-
-/* Rewind "file pointer" to start of ntdom group database */
-
-NSS_STATUS
-_nss_winbind_setgrent(void)
-{
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: setgrent\n", getpid());
-#endif
-
- if (num_gr_cache > 0) {
- ndx_gr_cache = num_gr_cache = 0;
- free_response(&getgrent_response);
- }
-
- return winbindd_request(WINBINDD_SETGRENT, NULL, NULL);
-}
-
-/* Close "file pointer" for ntdom group database */
-
-NSS_STATUS
-_nss_winbind_endgrent(void)
-{
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: endgrent\n", getpid());
-#endif
-
- if (num_gr_cache > 0) {
- ndx_gr_cache = num_gr_cache = 0;
- free_response(&getgrent_response);
- }
-
- return winbindd_request(WINBINDD_ENDGRENT, NULL, NULL);
-}
-
-/* Get next entry from ntdom group database */
-
-static NSS_STATUS
-winbind_getgrent(enum winbindd_cmd cmd,
- struct group *result,
- char *buffer, size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- static struct winbindd_request request;
- static int called_again;
-
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getgrent\n", getpid());
-#endif
-
- /* Return an entry from the cache if we have one, or if we are
- called again because we exceeded our static buffer. */
-
- if ((ndx_gr_cache < num_gr_cache) || called_again) {
- goto return_result;
- }
-
- /* Else call winbindd to get a bunch of entries */
-
- if (num_gr_cache > 0) {
- free_response(&getgrent_response);
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(getgrent_response);
-
- request.data.num_entries = MAX_GETGRENT_USERS;
-
- ret = winbindd_request(cmd, &request,
- &getgrent_response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- struct winbindd_gr *gr_cache;
- int mem_ofs;
-
- /* Fill cache */
-
- ndx_gr_cache = 0;
- num_gr_cache = getgrent_response.data.num_entries;
-
- /* Return a result */
-
- return_result:
-
- gr_cache = getgrent_response.extra_data;
-
- /* Check data is valid */
-
- if (gr_cache == NULL) {
- return NSS_STATUS_NOTFOUND;
- }
-
- /* Fill group membership. The offset into the extra data
- for the group membership is the reported offset plus the
- size of all the winbindd_gr records returned. */
-
- mem_ofs = gr_cache[ndx_gr_cache].gr_mem_ofs +
- num_gr_cache * sizeof(struct winbindd_gr);
-
- ret = fill_grent(result, &gr_cache[ndx_gr_cache],
- ((char *)getgrent_response.extra_data)+mem_ofs,
- &buffer, &buflen);
-
- /* Out of memory - try again */
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- called_again = True;
- *errnop = errno = ERANGE;
- return ret;
- }
-
- *errnop = 0;
- called_again = False;
- ndx_gr_cache++;
-
- /* If we've finished with this lot of results free cache */
-
- if (ndx_gr_cache == num_gr_cache) {
- ndx_gr_cache = num_gr_cache = 0;
- free_response(&getgrent_response);
- }
- }
-
- return ret;
-}
-
-
-NSS_STATUS
-_nss_winbind_getgrent_r(struct group *result,
- char *buffer, size_t buflen, int *errnop)
-{
- return winbind_getgrent(WINBINDD_GETGRENT, result, buffer, buflen, errnop);
-}
-
-NSS_STATUS
-_nss_winbind_getgrlst_r(struct group *result,
- char *buffer, size_t buflen, int *errnop)
-{
- return winbind_getgrent(WINBINDD_GETGRLST, result, buffer, buflen, errnop);
-}
-
-/* Return group struct from group name */
-
-NSS_STATUS
-_nss_winbind_getgrnam_r(const char *name,
- struct group *result, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- static struct winbindd_response response;
- struct winbindd_request request;
- static int keep_response;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getgrnam %s\n", getpid(), name);
-#endif
-
- /* If our static buffer needs to be expanded we are called again */
-
- if (!keep_response) {
-
- /* Call for the first time */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.groupname, name,
- sizeof(request.data.groupname));
- request.data.groupname
- [sizeof(request.data.groupname) - 1] = '\0';
-
- ret = winbindd_request(WINBINDD_GETGRNAM, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- ret = fill_grent(result, &response.data.gr,
- response.extra_data,
- &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = True;
- *errnop = errno = ERANGE;
- return ret;
- }
- }
-
- } else {
-
- /* We've been called again */
-
- ret = fill_grent(result, &response.data.gr,
- response.extra_data, &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = True;
- *errnop = errno = ERANGE;
- return ret;
- }
-
- keep_response = False;
- *errnop = 0;
- }
-
- free_response(&response);
- return ret;
-}
-
-/* Return group struct from gid */
-
-NSS_STATUS
-_nss_winbind_getgrgid_r(gid_t gid,
- struct group *result, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- static struct winbindd_response response;
- struct winbindd_request request;
- static int keep_response;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getgrgid %d\n", getpid(), gid);
-#endif
-
- /* If our static buffer needs to be expanded we are called again */
-
- if (!keep_response) {
-
- /* Call for the first time */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.gid = gid;
-
- ret = winbindd_request(WINBINDD_GETGRGID, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
-
- ret = fill_grent(result, &response.data.gr,
- response.extra_data,
- &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = True;
- *errnop = errno = ERANGE;
- return ret;
- }
- }
-
- } else {
-
- /* We've been called again */
-
- ret = fill_grent(result, &response.data.gr,
- response.extra_data, &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = True;
- *errnop = errno = ERANGE;
- return ret;
- }
-
- keep_response = False;
- *errnop = 0;
- }
-
- free_response(&response);
- return ret;
-}
-
-/* Initialise supplementary groups */
-
-NSS_STATUS
-_nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
- long int *size, gid_t **groups, long int limit,
- int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_request request;
- struct winbindd_response response;
- int i;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: initgroups %s (%d)\n", getpid(),
- user, group);
-#endif
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.username, user,
- sizeof(request.data.username) - 1);
-
- ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- int num_gids = response.data.num_entries;
- gid_t *gid_list = (gid_t *)response.extra_data;
-
- /* Copy group list to client */
-
- for (i = 0; i < num_gids; i++) {
-
- /* Skip primary group */
-
- if (gid_list[i] == group) continue;
-
- /* Add to buffer */
-
- if (*start == *size && limit <= 0) {
- (*groups) = realloc(
- (*groups), (2 * (*size) + 1) * sizeof(**groups));
- if (! *groups) goto done;
- *size = 2 * (*size) + 1;
- }
-
- if (*start == *size) goto done;
-
- (*groups)[*start] = gid_list[i];
- *start += 1;
-
- /* Filled buffer? */
-
- if (*start == limit) goto done;
- }
- }
-
- /* Back to your regularly scheduled programming */
-
- done:
- return ret;
-}
-
-#endif
diff --git a/source4/nsswitch/winbind_nss_config.h b/source4/nsswitch/winbind_nss_config.h
deleted file mode 100644
index 2faaa30d1b..0000000000
--- a/source4/nsswitch/winbind_nss_config.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#ifndef _WINBIND_NSS_CONFIG_H
-#define _WINBIND_NSS_CONFIG_H
-
-/* Include header files from data in config.h file */
-
-#ifndef NO_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#ifdef HAVE_UNIXSOCKET
-#include <sys/un.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#else
-#ifdef HAVE_SYS_FCNTL_H
-#include <sys/fcntl.h>
-#endif
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <pwd.h>
-#include "nsswitch/nss.h"
-
-/* Declarations for functions in winbind_nss.c
- needed in winbind_nss_solaris.c (solaris wrapper to nss) */
-
-NSS_STATUS _nss_winbind_setpwent(void);
-NSS_STATUS _nss_winbind_endpwent(void);
-NSS_STATUS _nss_winbind_getpwent_r(struct passwd* result, char* buffer,
- size_t buflen, int* errnop);
-NSS_STATUS _nss_winbind_getpwuid_r(uid_t, struct passwd*, char* buffer,
- size_t buflen, int* errnop);
-NSS_STATUS _nss_winbind_getpwnam_r(const char* name, struct passwd* result,
- char* buffer, size_t buflen, int* errnop);
-
-NSS_STATUS _nss_winbind_setgrent(void);
-NSS_STATUS _nss_winbind_endgrent(void);
-NSS_STATUS _nss_winbind_getgrent_r(struct group* result, char* buffer,
- size_t buflen, int* errnop);
-NSS_STATUS _nss_winbind_getgrnam_r(const char *name,
- struct group *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid,
- struct group *result, char *buffer,
- size_t buflen, int *errnop);
-
-/* I'm trying really hard not to include anything from smb.h with the
- result of some silly looking redeclaration of structures. */
-
-#ifndef _PSTRING
-#define _PSTRING
-#define PSTRING_LEN 1024
-#define FSTRING_LEN 256
-typedef char pstring[PSTRING_LEN];
-typedef char fstring[FSTRING_LEN];
-#endif
-
-#ifndef _BOOL
-#define _BOOL /* So we don't typedef BOOL again in vfs.h */
-#define False (0)
-#define True (1)
-#define Auto (2)
-typedef int BOOL;
-#endif
-
-#if !defined(uint32)
-#if (SIZEOF_INT == 4)
-#define uint32 unsigned int
-#elif (SIZEOF_LONG == 4)
-#define uint32 unsigned long
-#elif (SIZEOF_SHORT == 4)
-#define uint32 unsigned short
-#endif
-#endif
-
-#if !defined(uint16)
-#if (SIZEOF_SHORT == 4)
-#define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16;
-#else /* SIZEOF_SHORT != 4 */
-#define uint16 unsigned short
-#endif /* SIZEOF_SHORT != 4 */
-#endif
-
-#ifndef uint8
-#define uint8 unsigned char
-#endif
-
-/* zero a structure */
-#ifndef ZERO_STRUCT
-#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
-#endif
-
-/* zero a structure given a pointer to the structure */
-#ifndef ZERO_STRUCTP
-#define ZERO_STRUCTP(x) { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); }
-#endif
-
-/* Some systems (SCO) treat UNIX domain sockets as FIFOs */
-
-#ifndef S_IFSOCK
-#define S_IFSOCK S_IFIFO
-#endif
-
-#ifndef S_ISSOCK
-#define S_ISSOCK(mode) ((mode & S_IFSOCK) == S_IFSOCK)
-#endif
-
-#endif
diff --git a/source4/nsswitch/winbind_nss_solaris.c b/source4/nsswitch/winbind_nss_solaris.c
deleted file mode 100644
index f3bd05b77a..0000000000
--- a/source4/nsswitch/winbind_nss_solaris.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- Solaris NSS wrapper for winbind
- - Shirish Kalele 2000
-
- Based on Luke Howard's ldap_nss module for Solaris
- */
-
-/*
- Copyright (C) 1997-2003 Luke Howard.
- This file is part of the nss_ldap library.
-
- The nss_ldap library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The nss_ldap library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the nss_ldap library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <string.h>
-#include <pwd.h>
-#include "includes.h"
-#include <syslog.h>
-#if !defined(HPUX)
-#include <sys/syslog.h>
-#endif /*hpux*/
-#include "winbind_nss_config.h"
-
-#if defined(HAVE_NSS_COMMON_H) || defined(HPUX)
-
-#undef NSS_DEBUG
-
-#ifdef NSS_DEBUG
-#define NSS_DEBUG(str) syslog(LOG_DEBUG, "nss_winbind: %s", str);
-#else
-#define NSS_DEBUG(str) ;
-#endif
-
-#define NSS_ARGS(args) ((nss_XbyY_args_t *)args)
-
-#define make_pwent_str(dest, src) \
-{ \
- if((dest = get_static(buffer, buflen, strlen(src)+1)) == NULL) \
- { \
- *errnop = ERANGE; \
- NSS_DEBUG("ERANGE error"); \
- return NSS_STATUS_TRYAGAIN; \
- } \
- strcpy(dest, src); \
-}
-
-static NSS_STATUS _nss_winbind_setpwent_solwrap (nss_backend_t* be, void* args)
-{
- NSS_DEBUG("_nss_winbind_setpwent_solwrap");
- return _nss_winbind_setpwent();
-}
-
-static NSS_STATUS
-_nss_winbind_endpwent_solwrap (nss_backend_t * be, void *args)
-{
- NSS_DEBUG("_nss_winbind_endpwent_solwrap");
- return _nss_winbind_endpwent();
-}
-
-static NSS_STATUS
-_nss_winbind_getpwent_solwrap (nss_backend_t* be, void *args)
-{
- NSS_STATUS ret;
- char* buffer = NSS_ARGS(args)->buf.buffer;
- int buflen = NSS_ARGS(args)->buf.buflen;
- struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
- int* errnop = &NSS_ARGS(args)->erange;
- char logmsg[80];
-
- ret = _nss_winbind_getpwent_r(result, buffer,
- buflen, errnop);
-
- if(ret == NSS_STATUS_SUCCESS)
- {
- snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning user: %s\n",
- result->pw_name);
- NSS_DEBUG(logmsg);
- NSS_ARGS(args)->returnval = (void*) result;
- } else {
- snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning error: %d.\n",ret);
- NSS_DEBUG(logmsg);
- }
-
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_getpwnam_solwrap (nss_backend_t* be, void* args)
-{
- NSS_STATUS ret;
- struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
-
- NSS_DEBUG("_nss_winbind_getpwnam_solwrap");
-
- ret = _nss_winbind_getpwnam_r (NSS_ARGS(args)->key.name,
- result,
- NSS_ARGS(args)->buf.buffer,
- NSS_ARGS(args)->buf.buflen,
- &NSS_ARGS(args)->erange);
- if(ret == NSS_STATUS_SUCCESS)
- NSS_ARGS(args)->returnval = (void*) result;
-
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_getpwuid_solwrap(nss_backend_t* be, void* args)
-{
- NSS_STATUS ret;
- struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
-
- NSS_DEBUG("_nss_winbind_getpwuid_solwrap");
- ret = _nss_winbind_getpwuid_r (NSS_ARGS(args)->key.uid,
- result,
- NSS_ARGS(args)->buf.buffer,
- NSS_ARGS(args)->buf.buflen,
- &NSS_ARGS(args)->erange);
- if(ret == NSS_STATUS_SUCCESS)
- NSS_ARGS(args)->returnval = (void*) result;
-
- return ret;
-}
-
-static NSS_STATUS _nss_winbind_passwd_destr (nss_backend_t * be, void *args)
-{
- SAFE_FREE(be);
- NSS_DEBUG("_nss_winbind_passwd_destr");
- return NSS_STATUS_SUCCESS;
-}
-
-static nss_backend_op_t passwd_ops[] =
-{
- _nss_winbind_passwd_destr,
- _nss_winbind_endpwent_solwrap, /* NSS_DBOP_ENDENT */
- _nss_winbind_setpwent_solwrap, /* NSS_DBOP_SETENT */
- _nss_winbind_getpwent_solwrap, /* NSS_DBOP_GETENT */
- _nss_winbind_getpwnam_solwrap, /* NSS_DBOP_PASSWD_BYNAME */
- _nss_winbind_getpwuid_solwrap /* NSS_DBOP_PASSWD_BYUID */
-};
-
-nss_backend_t*
-_nss_winbind_passwd_constr (const char* db_name,
- const char* src_name,
- const char* cfg_args)
-{
- nss_backend_t *be;
-
- if(!(be = (nss_backend_t*) malloc(sizeof(nss_backend_t))) )
- return NULL;
-
- be->ops = passwd_ops;
- be->n_ops = sizeof(passwd_ops) / sizeof(nss_backend_op_t);
-
- NSS_DEBUG("Initialized nss_winbind passwd backend");
- return be;
-}
-
-/*****************************************************************
- GROUP database backend
- *****************************************************************/
-
-static NSS_STATUS _nss_winbind_setgrent_solwrap (nss_backend_t* be, void* args)
-{
- NSS_DEBUG("_nss_winbind_setgrent_solwrap");
- return _nss_winbind_setgrent();
-}
-
-static NSS_STATUS
-_nss_winbind_endgrent_solwrap (nss_backend_t * be, void *args)
-{
- NSS_DEBUG("_nss_winbind_endgrent_solwrap");
- return _nss_winbind_endgrent();
-}
-
-static NSS_STATUS
-_nss_winbind_getgrent_solwrap(nss_backend_t* be, void* args)
-{
- NSS_STATUS ret;
- char* buffer = NSS_ARGS(args)->buf.buffer;
- int buflen = NSS_ARGS(args)->buf.buflen;
- struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
- int* errnop = &NSS_ARGS(args)->erange;
- char logmsg[80];
-
- ret = _nss_winbind_getgrent_r(result, buffer,
- buflen, errnop);
-
- if(ret == NSS_STATUS_SUCCESS)
- {
- snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning group: %s\n", result->gr_name);
- NSS_DEBUG(logmsg);
- NSS_ARGS(args)->returnval = (void*) result;
- } else {
- snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning error: %d.\n", ret);
- NSS_DEBUG(logmsg);
- }
-
- return ret;
-
-}
-
-static NSS_STATUS
-_nss_winbind_getgrnam_solwrap(nss_backend_t* be, void* args)
-{
- NSS_STATUS ret;
- struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
-
- NSS_DEBUG("_nss_winbind_getgrnam_solwrap");
- ret = _nss_winbind_getgrnam_r(NSS_ARGS(args)->key.name,
- result,
- NSS_ARGS(args)->buf.buffer,
- NSS_ARGS(args)->buf.buflen,
- &NSS_ARGS(args)->erange);
-
- if(ret == NSS_STATUS_SUCCESS)
- NSS_ARGS(args)->returnval = (void*) result;
-
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_getgrgid_solwrap(nss_backend_t* be, void* args)
-{
- NSS_STATUS ret;
- struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
-
- NSS_DEBUG("_nss_winbind_getgrgid_solwrap");
- ret = _nss_winbind_getgrgid_r (NSS_ARGS(args)->key.gid,
- result,
- NSS_ARGS(args)->buf.buffer,
- NSS_ARGS(args)->buf.buflen,
- &NSS_ARGS(args)->erange);
-
- if(ret == NSS_STATUS_SUCCESS)
- NSS_ARGS(args)->returnval = (void*) result;
-
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_getgroupsbymember_solwrap(nss_backend_t* be, void* args)
-{
- NSS_DEBUG("_nss_winbind_getgroupsbymember");
- return NSS_STATUS_NOTFOUND;
-}
-
-static NSS_STATUS
-_nss_winbind_group_destr (nss_backend_t* be, void* args)
-{
- SAFE_FREE(be);
- NSS_DEBUG("_nss_winbind_group_destr");
- return NSS_STATUS_SUCCESS;
-}
-
-static nss_backend_op_t group_ops[] =
-{
- _nss_winbind_group_destr,
- _nss_winbind_endgrent_solwrap,
- _nss_winbind_setgrent_solwrap,
- _nss_winbind_getgrent_solwrap,
- _nss_winbind_getgrnam_solwrap,
- _nss_winbind_getgrgid_solwrap,
- _nss_winbind_getgroupsbymember_solwrap
-};
-
-nss_backend_t*
-_nss_winbind_group_constr (const char* db_name,
- const char* src_name,
- const char* cfg_args)
-{
- nss_backend_t* be;
-
- if(!(be = (nss_backend_t*) malloc(sizeof(nss_backend_t))) )
- return NULL;
-
- be->ops = group_ops;
- be->n_ops = sizeof(group_ops) / sizeof(nss_backend_op_t);
-
- NSS_DEBUG("Initialized nss_winbind group backend");
- return be;
-}
-
-#endif /* SUN_NSS */
-
-
diff --git a/source4/nsswitch/winbindd.c b/source4/nsswitch/winbindd.c
deleted file mode 100644
index 23394f5e8c..0000000000
--- a/source4/nsswitch/winbindd.c
+++ /dev/null
@@ -1,951 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) by Tim Potter 2000-2002
- Copyright (C) Andrew Tridgell 2002
-
- 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 "winbindd.h"
-
-BOOL opt_nocache = False;
-BOOL opt_dual_daemon = False;
-
-/* Reload configuration */
-
-static BOOL reload_services_file(BOOL test)
-{
- BOOL ret;
- pstring logfile;
-
- if (lp_loaded()) {
- pstring fname;
-
- pstrcpy(fname,lp_configfile());
- if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
- pstrcpy(dyn_CONFIGFILE,fname);
- test = False;
- }
- }
-
- snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE);
- lp_set_logfile(logfile);
-
- reopen_logs();
- ret = lp_load(dyn_CONFIGFILE,False,False,True);
-
- snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE);
- lp_set_logfile(logfile);
-
- reopen_logs();
- load_interfaces();
-
- return(ret);
-}
-
-/*******************************************************************
- Print out all talloc memory info.
-********************************************************************/
-
-void return_all_talloc_info(int msg_type, pid_t src_pid, void *buf, size_t len)
-{
- TALLOC_CTX *ctx = talloc_init("info context");
- char *info = NULL;
-
- if (!ctx)
- return;
-
- info = talloc_describe_all(ctx);
- if (info)
- DEBUG(10,(info));
- message_send_pid(src_pid, MSG_TALLOC_USAGE, info, info ? strlen(info) + 1: 0, True);
- talloc_destroy(ctx);
-}
-
-#if DUMP_CORE
-
-/**************************************************************************** **
- Prepare to dump a core file - carefully!
- **************************************************************************** */
-
-static BOOL dump_core(void)
-{
- char *p;
- pstring dname;
- pstrcpy( dname, lp_logfile() );
- if ((p=strrchr(dname,'/')))
- *p=0;
- pstrcat( dname, "/corefiles" );
- mkdir( dname, 0700 );
- sys_chown( dname, getuid(), getgid() );
- chmod( dname, 0700 );
- if ( chdir(dname) )
- return( False );
- umask( ~(0700) );
-
-#ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_CORE
- {
- struct rlimit rlp;
- getrlimit( RLIMIT_CORE, &rlp );
- rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
- setrlimit( RLIMIT_CORE, &rlp );
- getrlimit( RLIMIT_CORE, &rlp );
- DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
- }
-#endif
-#endif
-
- DEBUG(0,("Dumping core in %s\n",dname));
- abort();
- return( True );
-} /* dump_core */
-#endif
-
-/**************************************************************************** **
- Handle a fault..
- **************************************************************************** */
-
-static void fault_quit(void)
-{
-#if DUMP_CORE
- dump_core();
-#endif
-}
-
-static void winbindd_status(void)
-{
- struct winbindd_cli_state *tmp;
-
- DEBUG(0, ("winbindd status:\n"));
-
- /* Print client state information */
-
- DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
-
- if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
- DEBUG(2, ("\tclient list:\n"));
- for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
- DEBUG(2, ("\t\tpid %d, sock %d, rbl %d, wbl %d\n",
- tmp->pid, tmp->sock, tmp->read_buf_len,
- tmp->write_buf_len));
- }
- }
-}
-
-/* Print winbindd status to log file */
-
-static void print_winbindd_status(void)
-{
- winbindd_status();
- winbindd_idmap_status();
- winbindd_cm_status();
-}
-
-/* Flush client cache */
-
-static void flush_caches(void)
-{
- /* Clear cached user and group enumation info */
- wcache_flush_cache();
-}
-
-/* Handle the signal by unlinking socket and exiting */
-
-static void terminate(void)
-{
- pstring path;
-
- winbindd_idmap_close();
-
- /* Remove socket file */
- snprintf(path, sizeof(path), "%s/%s",
- WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
- unlink(path);
- exit(0);
-}
-
-static BOOL do_sigterm;
-
-static void termination_handler(int signum)
-{
- do_sigterm = True;
- sys_select_signal();
-}
-
-static BOOL do_sigusr2;
-
-static void sigusr2_handler(int signum)
-{
- do_sigusr2 = True;
- sys_select_signal();
-}
-
-static BOOL do_sighup;
-
-static void sighup_handler(int signum)
-{
- do_sighup = True;
- sys_select_signal();
-}
-
-struct dispatch_table {
- enum winbindd_cmd cmd;
- enum winbindd_result (*fn)(struct winbindd_cli_state *state);
- const char *winbindd_cmd_name;
-};
-
-static struct dispatch_table dispatch_table[] = {
-
- /* User functions */
-
- { WINBINDD_GETPWNAM, winbindd_getpwnam, "GETPWNAM" },
- { WINBINDD_GETPWUID, winbindd_getpwuid, "GETPWUID" },
-
- { WINBINDD_SETPWENT, winbindd_setpwent, "SETPWENT" },
- { WINBINDD_ENDPWENT, winbindd_endpwent, "ENDPWENT" },
- { WINBINDD_GETPWENT, winbindd_getpwent, "GETPWENT" },
-
- { WINBINDD_GETGROUPS, winbindd_getgroups, "GETGROUPS" },
-
- /* Group functions */
-
- { WINBINDD_GETGRNAM, winbindd_getgrnam, "GETGRNAM" },
- { WINBINDD_GETGRGID, winbindd_getgrgid, "GETGRGID" },
- { WINBINDD_SETGRENT, winbindd_setgrent, "SETGRENT" },
- { WINBINDD_ENDGRENT, winbindd_endgrent, "ENDGRENT" },
- { WINBINDD_GETGRENT, winbindd_getgrent, "GETGRENT" },
- { WINBINDD_GETGRLST, winbindd_getgrent, "GETGRLST" },
-
- /* PAM auth functions */
-
- { WINBINDD_PAM_AUTH, winbindd_pam_auth, "PAM_AUTH" },
- { WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" },
- { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" },
-
- /* Enumeration functions */
-
- { WINBINDD_LIST_USERS, winbindd_list_users, "LIST_USERS" },
- { WINBINDD_LIST_GROUPS, winbindd_list_groups, "LIST_GROUPS" },
- { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains, "LIST_TRUSTDOM" },
- { WINBINDD_SHOW_SEQUENCE, winbindd_show_sequence, "SHOW_SEQUENCE" },
-
- /* SID related functions */
-
- { WINBINDD_LOOKUPSID, winbindd_lookupsid, "LOOKUPSID" },
- { WINBINDD_LOOKUPNAME, winbindd_lookupname, "LOOKUPNAME" },
-
- /* Lookup related functions */
-
- { WINBINDD_SID_TO_UID, winbindd_sid_to_uid, "SID_TO_UID" },
- { WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" },
- { WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" },
- { WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" },
-
- /* Miscellaneous */
-
- { WINBINDD_CHECK_MACHACC, winbindd_check_machine_acct, "CHECK_MACHACC" },
- { WINBINDD_PING, winbindd_ping, "PING" },
- { WINBINDD_INFO, winbindd_info, "INFO" },
- { WINBINDD_INTERFACE_VERSION, winbindd_interface_version, "INTERFACE_VERSION" },
- { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
- { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
-
- /* WINS functions */
-
- { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
- { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
-
- /* End of list */
-
- { WINBINDD_NUM_CMDS, NULL, "NONE" }
-};
-
-static void process_request(struct winbindd_cli_state *state)
-{
- struct dispatch_table *table = dispatch_table;
-
- /* Free response data - we may be interrupted and receive another
- command before being able to send this data off. */
-
- SAFE_FREE(state->response.extra_data);
-
- ZERO_STRUCT(state->response);
-
- state->response.result = WINBINDD_ERROR;
- state->response.length = sizeof(struct winbindd_response);
-
- /* Process command */
-
- for (table = dispatch_table; table->fn; table++) {
- if (state->request.cmd == table->cmd) {
- DEBUG(10,("process_request: request fn %s\n", table->winbindd_cmd_name ));
- state->response.result = table->fn(state);
- break;
- }
- }
-
- if (!table->fn)
- DEBUG(10,("process_request: unknown request fn number %d\n", (int)state->request.cmd ));
-
- /* In case extra data pointer is NULL */
-
- if (!state->response.extra_data)
- state->response.length = sizeof(struct winbindd_response);
-}
-
-/* Process a new connection by adding it to the client connection list */
-
-static void new_connection(int listen_sock)
-{
- struct sockaddr_un sunaddr;
- struct winbindd_cli_state *state;
- socklen_t len;
- int sock;
-
- /* Accept connection */
-
- len = sizeof(sunaddr);
-
- do {
- sock = accept(listen_sock, (struct sockaddr *)&sunaddr, &len);
- } while (sock == -1 && errno == EINTR);
-
- if (sock == -1)
- return;
-
- DEBUG(6,("accepted socket %d\n", sock));
-
- /* Create new connection structure */
-
- if ((state = (struct winbindd_cli_state *)
- malloc(sizeof(*state))) == NULL)
- return;
-
- ZERO_STRUCTP(state);
- state->sock = sock;
-
- state->last_access = time(NULL);
-
- /* Add to connection list */
-
- winbindd_add_client(state);
-}
-
-/* Remove a client connection from client connection list */
-
-static void remove_client(struct winbindd_cli_state *state)
-{
- /* It's a dead client - hold a funeral */
-
- if (state != NULL) {
-
- /* Close socket */
-
- close(state->sock);
-
- /* Free any getent state */
-
- free_getent_state(state->getpwent_state);
- free_getent_state(state->getgrent_state);
-
- /* We may have some extra data that was not freed if the
- client was killed unexpectedly */
-
- SAFE_FREE(state->response.extra_data);
-
- /* Remove from list and free */
-
- winbindd_remove_client(state);
- SAFE_FREE(state);
- }
-}
-
-
-/* Shutdown client connection which has been idle for the longest time */
-
-static BOOL remove_idle_client(void)
-{
- struct winbindd_cli_state *state, *remove_state = NULL;
- time_t last_access = 0;
- int nidle = 0;
-
- for (state = winbindd_client_list(); state; state = state->next) {
- if (state->read_buf_len == 0 && state->write_buf_len == 0 &&
- !state->getpwent_state && !state->getgrent_state) {
- nidle++;
- if (!last_access || state->last_access < last_access) {
- last_access = state->last_access;
- remove_state = state;
- }
- }
- }
-
- if (remove_state) {
- DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
- nidle, remove_state->sock, (unsigned int)remove_state->pid));
- remove_client(remove_state);
- return True;
- }
-
- return False;
-}
-
-/* Process a complete received packet from a client */
-
-void winbind_process_packet(struct winbindd_cli_state *state)
-{
- /* Process request */
-
- /* Ensure null termination of entire request */
- state->request.null_term = '\0';
-
- state->pid = state->request.pid;
-
- process_request(state);
-
- /* Update client state */
-
- state->read_buf_len = 0;
- state->write_buf_len = sizeof(struct winbindd_response);
-
- /* we might need to send it to the dual daemon */
- if (opt_dual_daemon) {
- dual_send_request(state);
- }
-}
-
-/* Read some data from a client connection */
-
-void winbind_client_read(struct winbindd_cli_state *state)
-{
- int n;
-
- /* Read data */
-
- n = sys_read(state->sock, state->read_buf_len +
- (char *)&state->request,
- sizeof(state->request) - state->read_buf_len);
-
- DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n, sizeof(state->request) - n - state->read_buf_len ));
-
- /* Read failed, kill client */
-
- if (n == -1 || n == 0) {
- DEBUG(5,("read failed on sock %d, pid %d: %s\n",
- state->sock, state->pid,
- (n == -1) ? strerror(errno) : "EOF"));
-
- state->finished = True;
- return;
- }
-
- /* Update client state */
-
- state->read_buf_len += n;
- state->last_access = time(NULL);
-}
-
-/* Write some data to a client connection */
-
-static void client_write(struct winbindd_cli_state *state)
-{
- char *data;
- int num_written;
-
- /* Write some data */
-
- if (!state->write_extra_data) {
-
- /* Write response structure */
-
- data = (char *)&state->response + sizeof(state->response) -
- state->write_buf_len;
-
- } else {
-
- /* Write extra data */
-
- data = (char *)state->response.extra_data +
- state->response.length -
- sizeof(struct winbindd_response) -
- state->write_buf_len;
- }
-
- num_written = sys_write(state->sock, data, state->write_buf_len);
-
- DEBUG(10,("client_write: wrote %d bytes.\n", num_written ));
-
- /* Write failed, kill cilent */
-
- if (num_written == -1 || num_written == 0) {
-
- DEBUG(3,("write failed on sock %d, pid %d: %s\n",
- state->sock, state->pid,
- (num_written == -1) ? strerror(errno) : "EOF"));
-
- state->finished = True;
-
- SAFE_FREE(state->response.extra_data);
-
- return;
- }
-
- /* Update client state */
-
- state->write_buf_len -= num_written;
- state->last_access = time(NULL);
-
- /* Have we written all data? */
-
- if (state->write_buf_len == 0) {
-
- /* Take care of extra data */
-
- if (state->write_extra_data) {
-
- SAFE_FREE(state->response.extra_data);
-
- state->write_extra_data = False;
-
- DEBUG(10,("client_write: client_write: complete response written.\n"));
-
- } else if (state->response.length >
- sizeof(struct winbindd_response)) {
-
- /* Start writing extra data */
-
- state->write_buf_len =
- state->response.length -
- sizeof(struct winbindd_response);
-
- DEBUG(10,("client_write: need to write %d extra data bytes.\n", (int)state->write_buf_len));
-
- state->write_extra_data = True;
- }
- }
-}
-
-/* Process incoming clients on listen_sock. We use a tricky non-blocking,
- non-forking, non-threaded model which allows us to handle many
- simultaneous connections while remaining impervious to many denial of
- service attacks. */
-
-static void process_loop(void)
-{
- /* We'll be doing this a lot */
-
- while (1) {
- struct winbindd_cli_state *state;
- fd_set r_fds, w_fds;
- int maxfd, listen_sock, selret;
- struct timeval timeout;
-
- /* Handle messages */
-
- message_dispatch();
-
- /* rescan the trusted domains list. This must be done
- regularly to cope with transitive trusts */
- rescan_trusted_domains(False);
-
- /* Free up temporary memory */
-
- lp_talloc_free();
- main_loop_talloc_free();
-
- /* Initialise fd lists for select() */
-
- listen_sock = open_winbindd_socket();
-
- if (listen_sock == -1) {
- perror("open_winbind_socket");
- exit(1);
- }
-
- maxfd = listen_sock;
-
- FD_ZERO(&r_fds);
- FD_ZERO(&w_fds);
- FD_SET(listen_sock, &r_fds);
-
- timeout.tv_sec = WINBINDD_ESTABLISH_LOOP;
- timeout.tv_usec = 0;
-
- if (opt_dual_daemon) {
- maxfd = dual_select_setup(&w_fds, maxfd);
- }
-
- /* Set up client readers and writers */
-
- state = winbindd_client_list();
-
- while (state) {
-
- /* Dispose of client connection if it is marked as
- finished */
-
- if (state->finished) {
- struct winbindd_cli_state *next = state->next;
-
- remove_client(state);
- state = next;
- continue;
- }
-
- /* Select requires we know the highest fd used */
-
- if (state->sock > maxfd)
- maxfd = state->sock;
-
- /* Add fd for reading */
-
- if (state->read_buf_len != sizeof(state->request))
- FD_SET(state->sock, &r_fds);
-
- /* Add fd for writing */
-
- if (state->write_buf_len)
- FD_SET(state->sock, &w_fds);
-
- state = state->next;
- }
-
- /* Call select */
-
- selret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
-
- if (selret == 0)
- continue;
-
- if ((selret == -1 && errno != EINTR) || selret == 0) {
-
- /* Select error, something is badly wrong */
-
- perror("select");
- exit(1);
- }
-
- /* Create a new connection if listen_sock readable */
-
- if (selret > 0) {
-
- if (opt_dual_daemon) {
- dual_select(&w_fds);
- }
-
- if (FD_ISSET(listen_sock, &r_fds)) {
- while (winbindd_num_clients() > WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
- DEBUG(5,("winbindd: Exceeding %d client connections, removing idle connection.\n",
- WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
- if (!remove_idle_client()) {
- DEBUG(0,("winbindd: Exceeding %d client connections, no idle connection found\n",
- WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
- break;
- }
- }
- new_connection(listen_sock);
- }
-
- /* Process activity on client connections */
-
- for (state = winbindd_client_list(); state;
- state = state->next) {
-
- /* Data available for reading */
-
- if (FD_ISSET(state->sock, &r_fds)) {
-
- /* Read data */
-
- winbind_client_read(state);
-
- /*
- * If we have the start of a
- * packet, then check the
- * length field to make sure
- * the client's not talking
- * Mock Swedish.
- */
-
- if (state->read_buf_len >= sizeof(uint32)
- && *(uint32 *) &state->request != sizeof(state->request)) {
- DEBUG(0,("process_loop: Invalid request size from pid %d: %d bytes sent, should be %d\n",
- state->request.pid, *(uint32 *) &state->request, sizeof(state->request)));
-
- remove_client(state);
- break;
- }
-
- /* A request packet might be
- complete */
-
- if (state->read_buf_len ==
- sizeof(state->request)) {
- winbind_process_packet(state);
- }
- }
-
- /* Data available for writing */
-
- if (FD_ISSET(state->sock, &w_fds))
- client_write(state);
- }
- }
-
-#if 0
- winbindd_check_cache_size(time(NULL));
-#endif
-
- /* Check signal handling things */
-
- if (do_sigterm)
- terminate();
-
- if (do_sighup) {
-
- DEBUG(3, ("got SIGHUP\n"));
-
- /* Flush various caches */
-
- flush_caches();
- reload_services_file(True);
- do_sighup = False;
- }
-
- if (do_sigusr2) {
- print_winbindd_status();
- do_sigusr2 = False;
- }
- }
-}
-
-
-/*
- these are split out from the main winbindd for use by the background daemon
- */
-BOOL winbind_setup_common(void)
-{
- load_interfaces();
-
- if (!secrets_init()) {
-
- DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
- return False;
- }
-
- namecache_enable(); /* Enable netbios namecache */
-
- /* Check winbindd parameters are valid */
-
- ZERO_STRUCT(server_state);
-
- if (!winbindd_param_init())
- return False;
-
- /* Winbind daemon initialisation */
-
- if (!winbindd_idmap_init())
- return False;
-
- /* Unblock all signals we are interested in as they may have been
- blocked by the parent process. */
-
- BlockSignals(False, SIGINT);
- BlockSignals(False, SIGQUIT);
- BlockSignals(False, SIGTERM);
- BlockSignals(False, SIGUSR1);
- BlockSignals(False, SIGUSR2);
- BlockSignals(False, SIGHUP);
-
- /* Setup signal handlers */
-
- CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */
- CatchSignal(SIGQUIT, termination_handler);
- CatchSignal(SIGTERM, termination_handler);
-
- CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
-
- CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */
- CatchSignal(SIGHUP, sighup_handler);
-
- return True;
-}
-
-
-/* Main function */
-
-struct winbindd_state server_state; /* Server state information */
-
-
-static void usage(void)
-{
- printf("Usage: winbindd [options]\n");
- printf("\t-F daemon in foreground mode\n");
- printf("\t-S log to stdout\n");
- printf("\t-i interactive mode\n");
- printf("\t-B dual daemon mode\n");
- printf("\t-n disable cacheing\n");
- printf("\t-d level set debug level\n");
- printf("\t-s configfile choose smb.conf location\n");
- printf("\t-h show this help message\n");
-}
-
- int main(int argc, char **argv)
-{
- extern BOOL AllowDebugChange;
- pstring logfile;
- BOOL interactive = False;
- BOOL Fork = True;
- BOOL log_stdout = False;
- int opt;
-
- /* glibc (?) likes to print "User defined signal 1" and exit if a
- SIGUSR[12] is received before a handler is installed */
-
- CatchSignal(SIGUSR1, SIG_IGN);
- CatchSignal(SIGUSR2, SIG_IGN);
-
- fault_setup((void (*)(void *))fault_quit );
-
- snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE);
- lp_set_logfile(logfile);
-
- /* Initialise for running in non-root mode */
-
- sec_init();
-
- /* Set environment variable so we don't recursively call ourselves.
- This may also be useful interactively. */
-
- setenv(WINBINDD_DONT_ENV, "1", 1);
-
- /* Initialise samba/rpc client stuff */
-
- while ((opt = getopt(argc, argv, "FSid:s:nhB")) != EOF) {
- switch (opt) {
-
- case 'F':
- Fork = False;
- break;
- case 'S':
- log_stdout = True;
- break;
- /* Don't become a daemon */
- case 'i':
- interactive = True;
- log_stdout = True;
- Fork = False;
- break;
-
- /* dual daemon system */
- case 'B':
- opt_dual_daemon = True;
- break;
-
- /* disable cacheing */
- case 'n':
- opt_nocache = True;
- break;
-
- /* Run with specified debug level */
- case 'd':
- DEBUGLEVEL = atoi(optarg);
- AllowDebugChange = False;
- break;
-
- /* Load a different smb.conf file */
- case 's':
- pstrcpy(dyn_CONFIGFILE,optarg);
- break;
-
- case 'h':
- usage();
- exit(0);
-
- default:
- printf("Unknown option %c\n", (char)opt);
- exit(1);
- }
- }
-
- if (log_stdout && Fork) {
- printf("Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n");
- usage();
- exit(1);
- }
-
- snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE);
- lp_set_logfile(logfile);
- setup_logging("winbindd", log_stdout?DEBUG_STDOUT:DEBUG_FILE);
- reopen_logs();
-
- DEBUG(1, ("winbindd version %s started.\n", VERSION ) );
- DEBUGADD( 1, ( "Copyright The Samba Team 2000-2001\n" ) );
-
- if (!reload_services_file(False)) {
- DEBUG(0, ("error opening config file\n"));
- exit(1);
- }
-
- /* Setup names. */
-
- if (!init_names())
- exit(1);
-
- if (!interactive) {
- become_daemon(Fork);
- pidfile_create("winbindd");
- }
-
-
-#if HAVE_SETPGID
- /*
- * If we're interactive we want to set our own process group for
- * signal management.
- */
- if (interactive)
- setpgid( (pid_t)0, (pid_t)0);
-#endif
-
- if (!winbind_setup_common()) {
- return 1;
- }
-
- if (opt_dual_daemon) {
- do_dual_daemon();
- }
-
- /* Initialise messaging system */
-
- if (!message_init()) {
- DEBUG(0, ("unable to initialise messaging system\n"));
- exit(1);
- }
-
- register_msg_pool_usage();
- message_register(MSG_REQ_TALLOC_USAGE, return_all_talloc_info);
-
- /* Loop waiting for requests */
-
- process_loop();
-
- trustdom_cache_shutdown();
- uni_group_cache_shutdown();
- return 0;
-}
diff --git a/source4/nsswitch/winbindd.h b/source4/nsswitch/winbindd.h
deleted file mode 100644
index 42ef209faf..0000000000
--- a/source4/nsswitch/winbindd.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Anthony Liguori 2003
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#ifndef _WINBINDD_H
-#define _WINBINDD_H
-
-#include "includes.h"
-#include "nterr.h"
-
-#include "winbindd_nss.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/* Client state structure */
-
-struct winbindd_cli_state {
- struct winbindd_cli_state *prev, *next; /* Linked list pointers */
- int sock; /* Open socket from client */
- pid_t pid; /* pid of client */
- int read_buf_len, write_buf_len; /* Indexes in request/response */
- BOOL finished; /* Can delete from list */
- BOOL write_extra_data; /* Write extra_data field */
- time_t last_access; /* Time of last access (read or write) */
- struct winbindd_request request; /* Request from client */
- struct winbindd_response response; /* Respose to client */
- struct getent_state *getpwent_state; /* State for getpwent() */
- struct getent_state *getgrent_state; /* State for getgrent() */
-};
-
-/* State between get{pw,gr}ent() calls */
-
-struct getent_state {
- struct getent_state *prev, *next;
- void *sam_entries;
- uint32 sam_entry_index, num_sam_entries;
- BOOL got_sam_entries;
- fstring domain_name;
-};
-
-/* Storage for cached getpwent() user entries */
-
-struct getpwent_user {
- fstring name; /* Account name */
- fstring gecos; /* User information */
- DOM_SID user_sid; /* NT user and primary group SIDs */
- DOM_SID group_sid;
-};
-
-/* Server state structure */
-
-struct winbindd_state {
-
- /* User and group id pool */
-
- uid_t uid_low, uid_high; /* Range of uids to allocate */
- gid_t gid_low, gid_high; /* Range of gids to allocate */
-};
-
-extern struct winbindd_state server_state; /* Server information */
-
-typedef struct {
- char *acct_name;
- char *full_name;
- DOM_SID *user_sid; /* NT user and primary group SIDs */
- DOM_SID *group_sid;
-} WINBIND_USERINFO;
-
-/* Structures to hold per domain information */
-
-struct winbindd_domain {
- fstring name; /* Domain name */
- fstring alt_name; /* alt Domain name (if any) */
- DOM_SID sid; /* SID for this domain */
- BOOL native_mode; /* is this a win2k domain in native mode ? */
-
- /* Lookup methods for this domain (LDAP or RPC) */
-
- struct winbindd_methods *methods;
-
- /* Private data for the backends (used for connection cache) */
-
- void *private;
-
- /* Sequence number stuff */
-
- time_t last_seq_check;
- uint32 sequence_number;
-
- /* Linked list info */
-
- struct winbindd_domain *prev, *next;
-};
-
-/* per-domain methods. This is how LDAP vs RPC is selected
- */
-struct winbindd_methods {
- /* does this backend provide a consistent view of the data? (ie. is the primary group
- always correct) */
- BOOL consistent;
-
- /* get a list of users, returning a WINBIND_USERINFO for each one */
- NTSTATUS (*query_user_list)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- WINBIND_USERINFO **info);
-
- /* get a list of domain groups */
- NTSTATUS (*enum_dom_groups)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info);
-
- /* get a list of domain local groups */
- NTSTATUS (*enum_local_groups)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info);
-
- /* convert one user or group name to a sid */
- NTSTATUS (*name_to_sid)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *name,
- DOM_SID *sid,
- enum SID_NAME_USE *type);
-
- /* convert a sid to a user or group name */
- NTSTATUS (*sid_to_name)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *sid,
- char **name,
- enum SID_NAME_USE *type);
-
- /* lookup user info for a given SID */
- NTSTATUS (*query_user)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *user_sid,
- WINBIND_USERINFO *user_info);
-
- /* lookup all groups that a user is a member of. The backend
- can also choose to lookup by username or rid for this
- function */
- NTSTATUS (*lookup_usergroups)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *user_sid,
- uint32 *num_groups, DOM_SID ***user_gids);
-
- /* find all members of the group with the specified group_rid */
- NTSTATUS (*lookup_groupmem)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *group_sid,
- uint32 *num_names,
- DOM_SID ***sid_mem, char ***names,
- uint32 **name_types);
-
- /* return the current global sequence number */
- NTSTATUS (*sequence_number)(struct winbindd_domain *domain, uint32 *seq);
-
- /* enumerate trusted domains */
- NTSTATUS (*trusted_domains)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_domains,
- char ***names,
- char ***alt_names,
- DOM_SID **dom_sids);
-
- /* find the domain sid */
- NTSTATUS (*domain_sid)(struct winbindd_domain *domain,
- DOM_SID *sid);
-
- /* setup the list of alternate names for the domain, if any */
- NTSTATUS (*alternate_name)(struct winbindd_domain *domain);
-};
-
-/* Used to glue a policy handle and cli_state together */
-
-typedef struct {
- struct cli_state *cli;
- POLICY_HND pol;
-} CLI_POLICY_HND;
-
-/* Filled out by IDMAP backends */
-struct idmap_methods {
- /* Called when backend is first loaded */
- BOOL (*init)(void);
-
- BOOL (*get_sid_from_uid)(uid_t uid, DOM_SID *sid);
- BOOL (*get_sid_from_gid)(gid_t gid, DOM_SID *sid);
-
- BOOL (*get_uid_from_sid)(DOM_SID *sid, uid_t *uid);
- BOOL (*get_gid_from_sid)(DOM_SID *sid, gid_t *gid);
-
- /* Called when backend is unloaded */
- BOOL (*close)(void);
- /* Called to dump backend status */
- void (*status)(void);
-};
-
-#include "winbindd_proto.h"
-
-#include "rpc_parse.h"
-#include "rpc_client.h"
-
-#define WINBINDD_ESTABLISH_LOOP 30
-#define WINBINDD_RESCAN_FREQ 300
-
-#define DOM_SEQUENCE_NONE ((uint32)-1)
-
-#endif /* _WINBINDD_H */
diff --git a/source4/nsswitch/winbindd_ads.c b/source4/nsswitch/winbindd_ads.c
deleted file mode 100644
index de3757aa44..0000000000
--- a/source4/nsswitch/winbindd_ads.c
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind ADS backend functions
-
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 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 "winbindd.h"
-
-#ifdef HAVE_ADS
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/* the realm of our primary LDAP server */
-static char *primary_realm;
-
-
-/*
- return our ads connections structure for a domain. We keep the connection
- open to make things faster
-*/
-static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
-{
- ADS_STRUCT *ads;
- ADS_STATUS status;
-
- if (domain->private) {
- return (ADS_STRUCT *)domain->private;
- }
-
- /* we don't want this to affect the users ccache */
- setenv("KRB5CCNAME", "MEMORY:winbind_ccache", 1);
-
- ads = ads_init(domain->alt_name, domain->name, NULL);
- if (!ads) {
- DEBUG(1,("ads_init for domain %s failed\n", domain->name));
- return NULL;
- }
-
- /* the machine acct password might have change - fetch it every time */
- SAFE_FREE(ads->auth.password);
- ads->auth.password = secrets_fetch_machine_password();
-
- if (primary_realm) {
- SAFE_FREE(ads->auth.realm);
- ads->auth.realm = strdup(primary_realm);
- }
-
- status = ads_connect(ads);
- if (!ADS_ERR_OK(status) || !ads->config.realm) {
- extern struct winbindd_methods msrpc_methods;
- DEBUG(1,("ads_connect for domain %s failed: %s\n",
- domain->name, ads_errstr(status)));
- ads_destroy(&ads);
-
- /* if we get ECONNREFUSED then it might be a NT4
- server, fall back to MSRPC */
- if (status.error_type == ADS_ERROR_SYSTEM &&
- status.err.rc == ECONNREFUSED) {
- DEBUG(1,("Trying MSRPC methods\n"));
- domain->methods = &msrpc_methods;
- }
- return NULL;
- }
-
- /* remember our primary realm for trusted domain support */
- if (!primary_realm) {
- primary_realm = strdup(ads->config.realm);
- }
-
- domain->private = (void *)ads;
- return ads;
-}
-
-
-/* Query display info for a realm. This is the basic user list fn */
-static NTSTATUS query_user_list(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- WINBIND_USERINFO **info)
-{
- ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"userPrincipalName",
- "sAMAccountName",
- "name", "objectSid", "primaryGroupID",
- "sAMAccountType", NULL};
- int i, count;
- ADS_STATUS rc;
- void *res = NULL;
- void *msg = NULL;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-
- *num_entries = 0;
-
- DEBUG(3,("ads: query_user_list\n"));
-
- ads = ads_cached_connection(domain);
- if (!ads) goto done;
-
- rc = ads_search_retry(ads, &res, "(objectCategory=user)", attrs);
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
-
- count = ads_count_replies(ads, res);
- if (count == 0) {
- DEBUG(1,("query_user_list: No users found\n"));
- goto done;
- }
-
- (*info) = talloc_zero(mem_ctx, count * sizeof(**info));
- if (!*info) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- i = 0;
-
- for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
- char *name, *gecos;
- DOM_SID sid;
- DOM_SID *sid2;
- DOM_SID *group_sid;
- uint32 group;
- uint32 atype;
-
- if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) ||
- ads_atype_map(atype) != SID_NAME_USER) {
- DEBUG(1,("Not a user account? atype=0x%x\n", atype));
- continue;
- }
-
- name = ads_pull_username(ads, mem_ctx, msg);
- gecos = ads_pull_string(ads, mem_ctx, msg, "name");
- if (!ads_pull_sid(ads, msg, "objectSid", &sid)) {
- DEBUG(1,("No sid for %s !?\n", name));
- continue;
- }
- if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group)) {
- DEBUG(1,("No primary group for %s !?\n", name));
- continue;
- }
-
- sid2 = talloc(mem_ctx, sizeof(*sid2));
- if (!sid2) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- sid_copy(sid2, &sid);
-
- group_sid = rid_to_talloced_sid(domain, mem_ctx, group);
-
- (*info)[i].acct_name = name;
- (*info)[i].full_name = gecos;
- (*info)[i].user_sid = sid2;
- (*info)[i].group_sid = group_sid;
- i++;
- }
-
- (*num_entries) = i;
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads query_user_list gave %d entries\n", (*num_entries)));
-
-done:
- if (res) ads_msgfree(ads, res);
-
- return status;
-}
-
-/* list all domain groups */
-static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"userPrincipalName", "sAMAccountName",
- "name", "objectSid",
- "sAMAccountType", NULL};
- int i, count;
- ADS_STATUS rc;
- void *res = NULL;
- void *msg = NULL;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- uint32 group_flags;
-
- *num_entries = 0;
-
- DEBUG(3,("ads: enum_dom_groups\n"));
-
- ads = ads_cached_connection(domain);
- if (!ads) goto done;
-
- rc = ads_search_retry(ads, &res, "(objectCategory=group)", attrs);
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("enum_dom_groups ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
-
- count = ads_count_replies(ads, res);
- if (count == 0) {
- DEBUG(1,("enum_dom_groups: No groups found\n"));
- goto done;
- }
-
- (*info) = talloc_zero(mem_ctx, count * sizeof(**info));
- if (!*info) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- i = 0;
-
- group_flags = ATYPE_GLOBAL_GROUP;
- if ( domain->native_mode )
- group_flags |= ATYPE_LOCAL_GROUP;
-
- for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
- char *name, *gecos;
- DOM_SID sid;
- uint32 rid;
- uint32 account_type;
-
- if (!ads_pull_uint32(ads, msg, "sAMAccountType", &account_type) || !(account_type & group_flags) )
- continue;
-
- name = ads_pull_username(ads, mem_ctx, msg);
- gecos = ads_pull_string(ads, mem_ctx, msg, "name");
- if (!ads_pull_sid(ads, msg, "objectSid", &sid)) {
- DEBUG(1,("No sid for %s !?\n", name));
- continue;
- }
-
- if (!sid_peek_check_rid(&domain->sid, &sid, &rid)) {
- DEBUG(1,("No rid for %s !?\n", name));
- continue;
- }
-
- fstrcpy((*info)[i].acct_name, name);
- fstrcpy((*info)[i].acct_desc, gecos);
- (*info)[i].rid = rid;
- i++;
- }
-
- (*num_entries) = i;
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads enum_dom_groups gave %d entries\n", (*num_entries)));
-
-done:
- if (res) ads_msgfree(ads, res);
-
- return status;
-}
-
-/* list all domain local groups */
-static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- /*
- * This is a stub function only as we returned the domain
- * ocal groups in enum_dom_groups() if the domain->native field
- * was true. This is a simple performance optimization when
- * using LDAP.
- *
- * if we ever need to enumerate domain local groups separately,
- * then this the optimization in enum_dom_groups() will need
- * to be split out
- */
- *num_entries = 0;
-
- return NT_STATUS_OK;
-}
-
-/* convert a single name to a sid in a domain */
-static NTSTATUS name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *name,
- DOM_SID *sid,
- enum SID_NAME_USE *type)
-{
- ADS_STRUCT *ads;
-
- DEBUG(3,("ads: name_to_sid\n"));
-
- ads = ads_cached_connection(domain);
- if (!ads)
- return NT_STATUS_UNSUCCESSFUL;
-
- return ads_name_to_sid(ads, name, sid, type);
-}
-
-/* convert a sid to a user or group name */
-static NTSTATUS sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *sid,
- char **name,
- enum SID_NAME_USE *type)
-{
- ADS_STRUCT *ads = NULL;
- DEBUG(3,("ads: sid_to_name\n"));
- ads = ads_cached_connection(domain);
- if (!ads)
- return NT_STATUS_UNSUCCESSFUL;
-
- return ads_sid_to_name(ads, mem_ctx, sid, name, type);
-}
-
-
-/* convert a DN to a name, SID and name type
- this might become a major speed bottleneck if groups have
- lots of users, in which case we could cache the results
-*/
-static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
- const char *dn,
- char **name, uint32 *name_type, DOM_SID *sid)
-{
- char *exp;
- void *res = NULL;
- const char *attrs[] = {"userPrincipalName", "sAMAccountName",
- "objectSid", "sAMAccountType", NULL};
- ADS_STATUS rc;
- uint32 atype;
- char *escaped_dn = escape_ldap_string_alloc(dn);
-
- if (!escaped_dn) {
- return False;
- }
-
- asprintf(&exp, "(distinguishedName=%s)", dn);
- rc = ads_search_retry(ads, &res, exp, attrs);
- SAFE_FREE(exp);
- SAFE_FREE(escaped_dn);
-
- if (!ADS_ERR_OK(rc)) {
- goto failed;
- }
-
- (*name) = ads_pull_username(ads, mem_ctx, res);
-
- if (!ads_pull_uint32(ads, res, "sAMAccountType", &atype)) {
- goto failed;
- }
- (*name_type) = ads_atype_map(atype);
-
- if (!ads_pull_sid(ads, res, "objectSid", sid)) {
- goto failed;
- }
-
- if (res) ads_msgfree(ads, res);
- return True;
-
-failed:
- if (res) ads_msgfree(ads, res);
- return False;
-}
-
-/* Lookup user information from a rid */
-static NTSTATUS query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *sid,
- WINBIND_USERINFO *info)
-{
- ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"userPrincipalName",
- "sAMAccountName",
- "name",
- "primaryGroupID", NULL};
- ADS_STATUS rc;
- int count;
- void *msg = NULL;
- char *exp;
- char *sidstr;
- uint32 group_rid;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- DOM_SID *sid2;
- fstring sid_string;
-
- DEBUG(3,("ads: query_user\n"));
-
- ads = ads_cached_connection(domain);
- if (!ads) goto done;
-
- sidstr = sid_binstring(sid);
- asprintf(&exp, "(objectSid=%s)", sidstr);
- rc = ads_search_retry(ads, &msg, exp, attrs);
- free(exp);
- free(sidstr);
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("query_user(sid=%s) ads_search: %s\n", sid_to_string(sid_string, sid), ads_errstr(rc)));
- goto done;
- }
-
- count = ads_count_replies(ads, msg);
- if (count != 1) {
- DEBUG(1,("query_user(sid=%s): Not found\n", sid_to_string(sid_string, sid)));
- goto done;
- }
-
- info->acct_name = ads_pull_username(ads, mem_ctx, msg);
- info->full_name = ads_pull_string(ads, mem_ctx, msg, "name");
-
- if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) {
- DEBUG(1,("No primary group for %s !?\n", sid_to_string(sid_string, sid)));
- goto done;
- }
-
- sid2 = talloc(mem_ctx, sizeof(*sid2));
- if (!sid2) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
- sid_copy(sid2, sid);
-
- info->user_sid = sid2;
-
- info->group_sid = rid_to_talloced_sid(domain, mem_ctx, group_rid);
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads query_user gave %s\n", info->acct_name));
-done:
- if (msg) ads_msgfree(ads, msg);
-
- return status;
-}
-
-/* Lookup groups a user is a member of - alternate method, for when
- tokenGroups are not available. */
-static NTSTATUS lookup_usergroups_alt(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *user_dn,
- DOM_SID *primary_group,
- uint32 *num_groups, DOM_SID ***user_gids)
-{
- ADS_STATUS rc;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- int count;
- void *res = NULL;
- void *msg = NULL;
- char *exp;
- ADS_STRUCT *ads;
- const char *group_attrs[] = {"objectSid", NULL};
-
- ads = ads_cached_connection(domain);
- if (!ads) goto done;
-
- /* buggy server, no tokenGroups. Instead lookup what groups this user
- is a member of by DN search on member*/
- if (asprintf(&exp, "(&(member=%s)(objectClass=group))", user_dn) == -1) {
- DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn));
- return NT_STATUS_NO_MEMORY;
- }
-
- rc = ads_search_retry(ads, &res, exp, group_attrs);
- free(exp);
-
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("lookup_usergroups ads_search member=%s: %s\n", user_dn, ads_errstr(rc)));
- return ads_ntstatus(rc);
- }
-
- count = ads_count_replies(ads, res);
- if (count == 0) {
- DEBUG(5,("lookup_usergroups: No supp groups found\n"));
-
- status = ads_ntstatus(rc);
- goto done;
- }
-
- (*user_gids) = talloc_zero(mem_ctx, sizeof(**user_gids) * (count + 1));
- (*user_gids)[0] = primary_group;
-
- *num_groups = 1;
-
- for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
- DOM_SID group_sid;
-
- if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) {
- DEBUG(1,("No sid for this group ?!?\n"));
- continue;
- }
-
- if (sid_equal(&group_sid, primary_group)) continue;
-
- (*user_gids)[*num_groups] = talloc(mem_ctx, sizeof(***user_gids));
- if (!(*user_gids)[*num_groups]) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- sid_copy((*user_gids)[*num_groups], &group_sid);
-
- (*num_groups)++;
-
- }
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads lookup_usergroups (alt) for dn=%s\n", user_dn));
-done:
- if (res) ads_msgfree(ads, res);
- if (msg) ads_msgfree(ads, msg);
-
- return status;
-}
-
-/* Lookup groups a user is a member of. */
-static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *sid,
- uint32 *num_groups, DOM_SID ***user_gids)
-{
- ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"distinguishedName", NULL};
- const char *attrs2[] = {"tokenGroups", "primaryGroupID", NULL};
- ADS_STATUS rc;
- int count;
- void *msg = NULL;
- char *exp;
- char *user_dn;
- DOM_SID *sids;
- int i;
- DOM_SID *primary_group;
- uint32 primary_group_rid;
- char *sidstr;
- fstring sid_string;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(3,("ads: lookup_usergroups\n"));
- *num_groups = 0;
-
- ads = ads_cached_connection(domain);
- if (!ads) goto done;
-
- if (!(sidstr = sid_binstring(sid))) {
- DEBUG(1,("lookup_usergroups(sid=%s) sid_binstring returned NULL\n", sid_to_string(sid_string, sid)));
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
- if (asprintf(&exp, "(objectSid=%s)", sidstr) == -1) {
- free(sidstr);
- DEBUG(1,("lookup_usergroups(sid=%s) asprintf failed!\n", sid_to_string(sid_string, sid)));
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- rc = ads_search_retry(ads, &msg, exp, attrs);
- free(exp);
- free(sidstr);
-
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("lookup_usergroups(sid=%s) ads_search: %s\n", sid_to_string(sid_string, sid), ads_errstr(rc)));
- goto done;
- }
-
- user_dn = ads_pull_string(ads, mem_ctx, msg, "distinguishedName");
- if (!user_dn) {
- DEBUG(1,("lookup_usergroups(sid=%s) ads_search did not return a a distinguishedName!\n", sid_to_string(sid_string, sid)));
- if (msg) ads_msgfree(ads, msg);
- goto done;
- }
-
- if (msg) ads_msgfree(ads, msg);
-
- rc = ads_search_retry_dn(ads, &msg, user_dn, attrs2);
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: %s\n", sid_to_string(sid_string, sid), ads_errstr(rc)));
- goto done;
- }
-
- if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group_rid)) {
- DEBUG(1,("%s: No primary group for sid=%s !?\n", domain->name, sid_to_string(sid_string, sid)));
- goto done;
- }
-
- primary_group = rid_to_talloced_sid(domain, mem_ctx, primary_group_rid);
-
- count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids);
-
- if (msg) ads_msgfree(ads, msg);
-
- /* there must always be at least one group in the token,
- unless we are talking to a buggy Win2k server */
- if (count == 0) {
- return lookup_usergroups_alt(domain, mem_ctx, user_dn,
- primary_group,
- num_groups, user_gids);
- }
-
- (*user_gids) = talloc_zero(mem_ctx, sizeof(**user_gids) * (count + 1));
- (*user_gids)[0] = primary_group;
-
- *num_groups = 1;
-
- for (i=0;i<count;i++) {
- if (sid_equal(&sids[i], primary_group)) continue;
-
- (*user_gids)[*num_groups] = talloc(mem_ctx, sizeof(***user_gids));
- if (!(*user_gids)[*num_groups]) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- sid_copy((*user_gids)[*num_groups], &sids[i]);
- (*num_groups)++;
- }
-
- status = NT_STATUS_OK;
- DEBUG(3,("ads lookup_usergroups for sid=%s\n", sid_to_string(sid_string, sid)));
-done:
- return status;
-}
-
-/*
- find the members of a group, given a group rid and domain
- */
-static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *group_sid, uint32 *num_names,
- DOM_SID ***sid_mem, char ***names,
- uint32 **name_types)
-{
- ADS_STATUS rc;
- int count;
- void *res=NULL;
- ADS_STRUCT *ads = NULL;
- char *exp;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- char *sidstr;
- const char *attrs[] = {"member", NULL};
- char **members;
- int i, num_members;
- fstring sid_string;
-
- *num_names = 0;
-
- ads = ads_cached_connection(domain);
- if (!ads) goto done;
-
- sidstr = sid_binstring(group_sid);
-
- /* search for all members of the group */
- asprintf(&exp, "(objectSid=%s)",sidstr);
- rc = ads_search_retry(ads, &res, exp, attrs);
- free(exp);
- free(sidstr);
-
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
-
- count = ads_count_replies(ads, res);
- if (count == 0) {
- status = NT_STATUS_OK;
- goto done;
- }
-
- members = ads_pull_strings(ads, mem_ctx, res, "member");
- if (!members) {
- /* no members? ok ... */
- status = NT_STATUS_OK;
- goto done;
- }
-
- /* now we need to turn a list of members into rids, names and name types
- the problem is that the members are in the form of distinguised names
- */
- for (i=0;members[i];i++) /* noop */ ;
- num_members = i;
-
- (*sid_mem) = talloc_zero(mem_ctx, sizeof(**sid_mem) * num_members);
- (*name_types) = talloc_zero(mem_ctx, sizeof(**name_types) * num_members);
- (*names) = talloc_zero(mem_ctx, sizeof(**names) * num_members);
-
- for (i=0;i<num_members;i++) {
- uint32 name_type;
- char *name;
- DOM_SID sid;
-
- if (dn_lookup(ads, mem_ctx, members[i], &name, &name_type, &sid)) {
- (*names)[*num_names] = name;
- (*name_types)[*num_names] = name_type;
- (*sid_mem)[*num_names] = talloc(mem_ctx, sizeof(***sid_mem));
- if (!(*sid_mem)[*num_names]) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
- sid_copy((*sid_mem)[*num_names], &sid);
- (*num_names)++;
- }
- }
-
- status = NT_STATUS_OK;
- DEBUG(3,("ads lookup_groupmem for sid=%s\n", sid_to_string(sid_string, group_sid)));
-done:
- if (res) ads_msgfree(ads, res);
-
- return status;
-}
-
-
-/* find the sequence number for a domain */
-static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
-{
- ADS_STRUCT *ads = NULL;
- ADS_STATUS rc;
-
- *seq = DOM_SEQUENCE_NONE;
-
- ads = ads_cached_connection(domain);
- if (!ads) return NT_STATUS_UNSUCCESSFUL;
-
- rc = ads_USN(ads, seq);
- if (!ADS_ERR_OK(rc)) {
- /* its a dead connection */
- ads_destroy(&ads);
- domain->private = NULL;
- }
- return ads_ntstatus(rc);
-}
-
-/* get a list of trusted domains */
-static NTSTATUS trusted_domains(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_domains,
- char ***names,
- char ***alt_names,
- DOM_SID **dom_sids)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
-
- *num_domains = 0;
- *names = NULL;
-
- ads = ads_cached_connection(domain);
- if (!ads) return NT_STATUS_UNSUCCESSFUL;
-
- rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, alt_names, dom_sids);
-
- return ads_ntstatus(rc);
-}
-
-/* find the domain sid for a domain */
-static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
-
- ads = ads_cached_connection(domain);
- if (!ads) return NT_STATUS_UNSUCCESSFUL;
-
- rc = ads_domain_sid(ads, sid);
-
- if (!ADS_ERR_OK(rc)) {
- /* its a dead connection */
- ads_destroy(&ads);
- domain->private = NULL;
- }
-
- return ads_ntstatus(rc);
-}
-
-
-/* find alternate names list for the domain - for ADS this is the
- netbios name */
-static NTSTATUS alternate_name(struct winbindd_domain *domain)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- TALLOC_CTX *ctx;
- char *workgroup;
-
- ads = ads_cached_connection(domain);
- if (!ads) return NT_STATUS_UNSUCCESSFUL;
-
- if (!(ctx = talloc_init("alternate_name"))) {
- return NT_STATUS_NO_MEMORY;
- }
-
- rc = ads_workgroup_name(ads, ctx, &workgroup);
-
- if (ADS_ERR_OK(rc)) {
- fstrcpy(domain->name, workgroup);
- fstrcpy(domain->alt_name, ads->config.realm);
- strupper(domain->alt_name);
- strupper(domain->name);
- }
-
- talloc_destroy(ctx);
-
- return ads_ntstatus(rc);
-}
-
-/* the ADS backend methods are exposed via this structure */
-struct winbindd_methods ads_methods = {
- True,
- query_user_list,
- enum_dom_groups,
- enum_local_groups,
- name_to_sid,
- sid_to_name,
- query_user,
- lookup_usergroups,
- lookup_groupmem,
- sequence_number,
- trusted_domains,
- domain_sid,
- alternate_name
-};
-
-#endif
diff --git a/source4/nsswitch/winbindd_cache.c b/source4/nsswitch/winbindd_cache.c
deleted file mode 100644
index 5fb59e7467..0000000000
--- a/source4/nsswitch/winbindd_cache.c
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind cache backend functions
-
- Copyright (C) Andrew Tridgell 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 "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-struct winbind_cache {
- struct winbindd_methods *backend;
- TDB_CONTEXT *tdb;
-};
-
-struct cache_entry {
- NTSTATUS status;
- uint32 sequence_number;
- uint8 *data;
- uint32 len, ofs;
-};
-
-#define WINBINDD_MAX_CACHE_SIZE (50*1024*1024)
-
-static struct winbind_cache *wcache;
-
-/* flush the cache */
-void wcache_flush_cache(void)
-{
- extern BOOL opt_nocache;
-
- if (!wcache) return;
- if (wcache->tdb) {
- tdb_close(wcache->tdb);
- wcache->tdb = NULL;
- }
- if (opt_nocache) return;
-
- wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000,
- TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0600);
-
- if (!wcache->tdb) {
- DEBUG(0,("Failed to open winbindd_cache.tdb!\n"));
- }
-}
-
-void winbindd_check_cache_size(time_t t)
-{
- static time_t last_check_time;
- struct stat st;
-
- if (last_check_time == (time_t)0)
- last_check_time = t;
-
- if (t - last_check_time < 60 && t - last_check_time > 0)
- return;
-
- if (wcache == NULL || wcache->tdb == NULL) {
- DEBUG(0, ("Unable to check size of tdb cache - cache not open !\n"));
- return;
- }
-
- if (fstat(wcache->tdb->fd, &st) == -1) {
- DEBUG(0, ("Unable to check size of tdb cache %s!\n", strerror(errno) ));
- return;
- }
-
- if (st.st_size > WINBINDD_MAX_CACHE_SIZE) {
- DEBUG(10,("flushing cache due to size (%lu) > (%lu)\n",
- (unsigned long)st.st_size,
- (unsigned long)WINBINDD_MAX_CACHE_SIZE));
- wcache_flush_cache();
- }
-}
-
-/* get the winbind_cache structure */
-static struct winbind_cache *get_cache(struct winbindd_domain *domain)
-{
- extern struct winbindd_methods msrpc_methods;
- struct winbind_cache *ret = wcache;
-
- if (ret) return ret;
-
- ret = smb_xmalloc(sizeof(*ret));
- ZERO_STRUCTP(ret);
- switch (lp_security()) {
-#ifdef HAVE_ADS
- case SEC_ADS: {
- extern struct winbindd_methods ads_methods;
- ret->backend = &ads_methods;
- break;
- }
-#endif
- default:
- ret->backend = &msrpc_methods;
- }
-
- wcache = ret;
- wcache_flush_cache();
-
- return ret;
-}
-
-/*
- free a centry structure
-*/
-static void centry_free(struct cache_entry *centry)
-{
- if (!centry) return;
- SAFE_FREE(centry->data);
- free(centry);
-}
-
-
-/*
- pull a uint32 from a cache entry
-*/
-static uint32 centry_uint32(struct cache_entry *centry)
-{
- uint32 ret;
- if (centry->len - centry->ofs < 4) {
- DEBUG(0,("centry corruption? needed 4 bytes, have %d\n",
- centry->len - centry->ofs));
- smb_panic("centry_uint32");
- }
- ret = IVAL(centry->data, centry->ofs);
- centry->ofs += 4;
- return ret;
-}
-
-/*
- pull a uint8 from a cache entry
-*/
-static uint8 centry_uint8(struct cache_entry *centry)
-{
- uint8 ret;
- if (centry->len - centry->ofs < 1) {
- DEBUG(0,("centry corruption? needed 1 bytes, have %d\n",
- centry->len - centry->ofs));
- smb_panic("centry_uint32");
- }
- ret = CVAL(centry->data, centry->ofs);
- centry->ofs += 1;
- return ret;
-}
-
-/* pull a string from a cache entry, using the supplied
- talloc context
-*/
-static char *centry_string(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
-{
- uint32 len;
- char *ret;
-
- len = centry_uint8(centry);
-
- if (len == 0xFF) {
- /* a deliberate NULL string */
- return NULL;
- }
-
- if (centry->len - centry->ofs < len) {
- DEBUG(0,("centry corruption? needed %d bytes, have %d\n",
- len, centry->len - centry->ofs));
- smb_panic("centry_string");
- }
-
- ret = talloc(mem_ctx, len+1);
- if (!ret) {
- smb_panic("centry_string out of memory\n");
- }
- memcpy(ret,centry->data + centry->ofs, len);
- ret[len] = 0;
- centry->ofs += len;
- return ret;
-}
-
-/* pull a string from a cache entry, using the supplied
- talloc context
-*/
-static DOM_SID *centry_sid(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
-{
- DOM_SID *sid;
- char *sid_string;
- sid = talloc(mem_ctx, sizeof(*sid));
- if (!sid) return NULL;
-
- sid_string = centry_string(centry, mem_ctx);
- if (!string_to_sid(sid, sid_string)) {
- return NULL;
- }
- return sid;
-}
-
-/* the server is considered down if it can't give us a sequence number */
-static BOOL wcache_server_down(struct winbindd_domain *domain)
-{
- if (!wcache->tdb) return False;
- return (domain->sequence_number == DOM_SEQUENCE_NONE);
-}
-
-
-/*
- refresh the domain sequence number. If force is True
- then always refresh it, no matter how recently we fetched it
-*/
-static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force)
-{
- NTSTATUS status;
- unsigned time_diff;
- unsigned cache_time = lp_winbind_cache_time();
-
- /* trying to reconnect is expensive, don't do it too often */
- if (domain->sequence_number == DOM_SEQUENCE_NONE) {
- cache_time *= 8;
- }
-
- time_diff = time(NULL) - domain->last_seq_check;
-
- /* see if we have to refetch the domain sequence number */
- if (!force && (time_diff < cache_time)) {
- return;
- }
-
- status = wcache->backend->sequence_number(domain, &domain->sequence_number);
-
- if (!NT_STATUS_IS_OK(status)) {
- domain->sequence_number = DOM_SEQUENCE_NONE;
- }
-
- domain->last_seq_check = time(NULL);
-}
-
-/*
- decide if a cache entry has expired
-*/
-static BOOL centry_expired(struct winbindd_domain *domain, struct cache_entry *centry)
-{
- /* if the server is OK and our cache entry came from when it was down then
- the entry is invalid */
- if (domain->sequence_number != DOM_SEQUENCE_NONE &&
- centry->sequence_number == DOM_SEQUENCE_NONE) {
- return True;
- }
-
- /* if the server is down or the cache entry is not older than the
- current sequence number then it is OK */
- if (wcache_server_down(domain) ||
- centry->sequence_number == domain->sequence_number) {
- return False;
- }
-
- /* it's expired */
- return True;
-}
-
-/*
- fetch an entry from the cache, with a varargs key. auto-fetch the sequence
- number and return status
-*/
-static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
- struct winbindd_domain *domain,
- const char *format, ...) PRINTF_ATTRIBUTE(3,4);
-static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
- struct winbindd_domain *domain,
- const char *format, ...)
-{
- va_list ap;
- char *kstr;
- TDB_DATA data;
- struct cache_entry *centry;
- TDB_DATA key;
-
- refresh_sequence_number(domain, False);
-
- va_start(ap, format);
- smb_xvasprintf(&kstr, format, ap);
- va_end(ap);
-
- key.dptr = kstr;
- key.dsize = strlen(kstr);
- data = tdb_fetch(wcache->tdb, key);
- free(kstr);
- if (!data.dptr) {
- /* a cache miss */
- return NULL;
- }
-
- centry = smb_xmalloc(sizeof(*centry));
- centry->data = data.dptr;
- centry->len = data.dsize;
- centry->ofs = 0;
-
- if (centry->len < 8) {
- /* huh? corrupt cache? */
- centry_free(centry);
- return NULL;
- }
-
- centry->status = NT_STATUS(centry_uint32(centry));
- centry->sequence_number = centry_uint32(centry);
-
- if (centry_expired(domain, centry)) {
- extern BOOL opt_dual_daemon;
-
- if (opt_dual_daemon) {
- extern BOOL background_process;
- background_process = True;
- } else {
- centry_free(centry);
- return NULL;
- }
- }
-
- return centry;
-}
-
-/*
- make sure we have at least len bytes available in a centry
-*/
-static void centry_expand(struct cache_entry *centry, uint32 len)
-{
- uint8 *p;
- if (centry->len - centry->ofs >= len) return;
- centry->len *= 2;
- p = realloc(centry->data, centry->len);
- if (!p) {
- DEBUG(0,("out of memory: needed %d bytes in centry_expand\n", centry->len));
- smb_panic("out of memory in centry_expand");
- }
- centry->data = p;
-}
-
-/*
- push a uint32 into a centry
-*/
-static void centry_put_uint32(struct cache_entry *centry, uint32 v)
-{
- centry_expand(centry, 4);
- SIVAL(centry->data, centry->ofs, v);
- centry->ofs += 4;
-}
-
-/*
- push a uint8 into a centry
-*/
-static void centry_put_uint8(struct cache_entry *centry, uint8 v)
-{
- centry_expand(centry, 1);
- SCVAL(centry->data, centry->ofs, v);
- centry->ofs += 1;
-}
-
-/*
- push a string into a centry
- */
-static void centry_put_string(struct cache_entry *centry, const char *s)
-{
- int len;
-
- if (!s) {
- /* null strings are marked as len 0xFFFF */
- centry_put_uint8(centry, 0xFF);
- return;
- }
-
- len = strlen(s);
- /* can't handle more than 254 char strings. Truncating is probably best */
- if (len > 254) len = 254;
- centry_put_uint8(centry, len);
- centry_expand(centry, len);
- memcpy(centry->data + centry->ofs, s, len);
- centry->ofs += len;
-}
-
-static void centry_put_sid(struct cache_entry *centry, const DOM_SID *sid)
-{
- int len;
- fstring sid_string;
- centry_put_string(centry, sid_to_string(sid_string, sid));
-}
-
-/*
- start a centry for output. When finished, call centry_end()
-*/
-struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status)
-{
- struct cache_entry *centry;
-
- if (!wcache->tdb) return NULL;
-
- centry = smb_xmalloc(sizeof(*centry));
-
- centry->len = 8192; /* reasonable default */
- centry->data = smb_xmalloc(centry->len);
- centry->ofs = 0;
- centry->sequence_number = domain->sequence_number;
- centry_put_uint32(centry, NT_STATUS_V(status));
- centry_put_uint32(centry, centry->sequence_number);
- return centry;
-}
-
-/*
- finish a centry and write it to the tdb
-*/
-static void centry_end(struct cache_entry *centry, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
-static void centry_end(struct cache_entry *centry, const char *format, ...)
-{
- va_list ap;
- char *kstr;
- TDB_DATA key, data;
-
- va_start(ap, format);
- smb_xvasprintf(&kstr, format, ap);
- va_end(ap);
-
- key.dptr = kstr;
- key.dsize = strlen(kstr);
- data.dptr = centry->data;
- data.dsize = centry->ofs;
-
- tdb_store(wcache->tdb, key, data, TDB_REPLACE);
- free(kstr);
-}
-
-static void wcache_save_name_to_sid(struct winbindd_domain *domain,
- NTSTATUS status,
- const char *name, DOM_SID *sid,
- enum SID_NAME_USE type)
-{
- struct cache_entry *centry;
- uint32 len;
- fstring uname;
- fstring sid_string;
-
- centry = centry_start(domain, status);
- if (!centry) return;
- centry_put_sid(centry, sid);
- fstrcpy(uname, name);
- strupper(uname);
- centry_end(centry, "NS/%s", sid_to_string(sid_string, sid));
- centry_free(centry);
-}
-
-static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status,
- DOM_SID *sid, const char *name, enum SID_NAME_USE type)
-{
- struct cache_entry *centry;
- fstring sid_string;
-
- centry = centry_start(domain, status);
- if (!centry) return;
- if (NT_STATUS_IS_OK(status)) {
- centry_put_uint32(centry, type);
- centry_put_string(centry, name);
- }
- centry_end(centry, "SN/%s", sid_to_string(sid_string, sid));
- centry_free(centry);
-}
-
-
-static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, WINBIND_USERINFO *info)
-{
- struct cache_entry *centry;
- fstring sid_string;
-
- centry = centry_start(domain, status);
- if (!centry) return;
- centry_put_string(centry, info->acct_name);
- centry_put_string(centry, info->full_name);
- centry_put_sid(centry, info->user_sid);
- centry_put_sid(centry, info->group_sid);
- centry_end(centry, "U/%s", sid_to_string(sid_string, info->user_sid));
- centry_free(centry);
-}
-
-
-/* Query display info. This is the basic user list fn */
-static NTSTATUS query_user_list(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- WINBIND_USERINFO **info)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "UL/%s", domain->name);
- if (!centry) goto do_query;
-
- *num_entries = centry_uint32(centry);
-
- if (*num_entries == 0) goto do_cached;
-
- (*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info)) smb_panic("query_user_list out of memory");
- for (i=0; i<(*num_entries); i++) {
- (*info)[i].acct_name = centry_string(centry, mem_ctx);
- (*info)[i].full_name = centry_string(centry, mem_ctx);
- (*info)[i].user_sid = centry_sid(centry, mem_ctx);
- (*info)[i].group_sid = centry_sid(centry, mem_ctx);
- }
-
-do_cached:
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- *num_entries = 0;
- *info = NULL;
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
-
- status = cache->backend->query_user_list(domain, mem_ctx, num_entries, info);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- centry = centry_start(domain, status);
- if (!centry) goto skip_save;
- centry_put_uint32(centry, *num_entries);
- for (i=0; i<(*num_entries); i++) {
- centry_put_string(centry, (*info)[i].acct_name);
- centry_put_string(centry, (*info)[i].full_name);
- centry_put_sid(centry, (*info)[i].user_sid);
- centry_put_sid(centry, (*info)[i].group_sid);
- if (cache->backend->consistent) {
- /* when the backend is consistent we can pre-prime some mappings */
- wcache_save_name_to_sid(domain, NT_STATUS_OK,
- (*info)[i].acct_name,
- (*info)[i].user_sid,
- SID_NAME_USER);
- wcache_save_sid_to_name(domain, NT_STATUS_OK,
- (*info)[i].user_sid,
- (*info)[i].acct_name,
- SID_NAME_USER);
- wcache_save_user(domain, NT_STATUS_OK, &(*info)[i]);
- }
- }
- centry_end(centry, "UL/%s", domain->name);
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-/* list all domain groups */
-static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "GL/%s/domain", domain->name);
- if (!centry) goto do_query;
-
- *num_entries = centry_uint32(centry);
-
- if (*num_entries == 0) goto do_cached;
-
- (*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info)) smb_panic("enum_dom_groups out of memory");
- for (i=0; i<(*num_entries); i++) {
- fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
- fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
- (*info)[i].rid = centry_uint32(centry);
- }
-
-do_cached:
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- *num_entries = 0;
- *info = NULL;
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
-
- status = cache->backend->enum_dom_groups(domain, mem_ctx, num_entries, info);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- centry = centry_start(domain, status);
- if (!centry) goto skip_save;
- centry_put_uint32(centry, *num_entries);
- for (i=0; i<(*num_entries); i++) {
- centry_put_string(centry, (*info)[i].acct_name);
- centry_put_string(centry, (*info)[i].acct_desc);
- centry_put_uint32(centry, (*info)[i].rid);
- }
- centry_end(centry, "GL/%s/domain", domain->name);
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-/* list all domain groups */
-static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "GL/%s/local", domain->name);
- if (!centry) goto do_query;
-
- *num_entries = centry_uint32(centry);
-
- if (*num_entries == 0) goto do_cached;
-
- (*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info)) smb_panic("enum_dom_groups out of memory");
- for (i=0; i<(*num_entries); i++) {
- fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
- fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
- (*info)[i].rid = centry_uint32(centry);
- }
-
-do_cached:
-
- /* If we are returning cached data and the domain controller
- is down then we don't know whether the data is up to date
- or not. Return NT_STATUS_MORE_PROCESSING_REQUIRED to
- indicate this. */
-
- if (wcache_server_down(domain)) {
- DEBUG(10, ("query_user_list: returning cached user list and server was down\n"));
- status = NT_STATUS_MORE_PROCESSING_REQUIRED;
- } else
- status = centry->status;
-
- centry_free(centry);
- return status;
-
-do_query:
- *num_entries = 0;
- *info = NULL;
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
-
- status = cache->backend->enum_local_groups(domain, mem_ctx, num_entries, info);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- centry = centry_start(domain, status);
- if (!centry) goto skip_save;
- centry_put_uint32(centry, *num_entries);
- for (i=0; i<(*num_entries); i++) {
- centry_put_string(centry, (*info)[i].acct_name);
- centry_put_string(centry, (*info)[i].acct_desc);
- centry_put_uint32(centry, (*info)[i].rid);
- }
- centry_end(centry, "GL/%s/local", domain->name);
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-/* convert a single name to a sid in a domain */
-static NTSTATUS name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *name,
- DOM_SID *sid,
- enum SID_NAME_USE *type)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- fstring uname;
- DOM_SID *sid2;
-
- if (!cache->tdb) goto do_query;
-
- fstrcpy(uname, name);
- strupper(uname);
- centry = wcache_fetch(cache, domain, "NS/%s/%s", domain->name, uname);
- if (!centry) goto do_query;
- *type = centry_uint32(centry);
- sid2 = centry_sid(centry, mem_ctx);
- if (!sid2) {
- ZERO_STRUCTP(sid);
- } else {
- sid_copy(sid, sid2);
- }
-
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- ZERO_STRUCTP(sid);
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->name_to_sid(domain, mem_ctx, name, sid, type);
-
- /* and save it */
- wcache_save_name_to_sid(domain, status, name, sid, *type);
-
- /* We can't save the sid to name mapping as we don't know the
- correct case of the name without looking it up */
-
- return status;
-}
-
-/* convert a sid to a user or group name. The sid is guaranteed to be in the domain
- given */
-static NTSTATUS sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *sid,
- char **name,
- enum SID_NAME_USE *type)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- fstring sid_string;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "SN/%s", sid_to_string(sid_string, sid));
- if (!centry) goto do_query;
- if (NT_STATUS_IS_OK(centry->status)) {
- *type = centry_uint32(centry);
- *name = centry_string(centry, mem_ctx);
- }
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- *name = NULL;
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->sid_to_name(domain, mem_ctx, sid, name, type);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- wcache_save_sid_to_name(domain, status, sid, *name, *type);
- wcache_save_name_to_sid(domain, status, *name, sid, *type);
-
- return status;
-}
-
-
-/* Lookup user information from a rid */
-static NTSTATUS query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *user_sid,
- WINBIND_USERINFO *info)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- fstring sid_string;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "U/%s", sid_to_string(sid_string, user_sid));
- if (!centry) goto do_query;
-
- info->acct_name = centry_string(centry, mem_ctx);
- info->full_name = centry_string(centry, mem_ctx);
- info->user_sid = centry_sid(centry, mem_ctx);
- info->group_sid = centry_sid(centry, mem_ctx);
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- ZERO_STRUCTP(info);
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
-
- status = cache->backend->query_user(domain, mem_ctx, user_sid, info);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- wcache_save_user(domain, status, info);
-
- return status;
-}
-
-
-/* Lookup groups a user is a member of. */
-static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *user_sid,
- uint32 *num_groups, DOM_SID ***user_gids)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
- fstring sid_string;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "UG/%s", sid_to_string(sid_string, user_sid));
- if (!centry) goto do_query;
-
- *num_groups = centry_uint32(centry);
-
- if (*num_groups == 0) goto do_cached;
-
- (*user_gids) = talloc(mem_ctx, sizeof(**user_gids) * (*num_groups));
- if (! (*user_gids)) smb_panic("lookup_usergroups out of memory");
- for (i=0; i<(*num_groups); i++) {
- (*user_gids)[i] = centry_sid(centry, mem_ctx);
- }
-
-do_cached:
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- (*num_groups) = 0;
- (*user_gids) = NULL;
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->lookup_usergroups(domain, mem_ctx, user_sid, num_groups, user_gids);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- centry = centry_start(domain, status);
- if (!centry) goto skip_save;
- centry_put_uint32(centry, *num_groups);
- for (i=0; i<(*num_groups); i++) {
- centry_put_sid(centry, (*user_gids)[i]);
- }
- centry_end(centry, "UG/%s", sid_to_string(sid_string, user_sid));
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-
-static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *group_sid, uint32 *num_names,
- DOM_SID ***sid_mem, char ***names,
- uint32 **name_types)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
- fstring sid_string;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "GM/%s", sid_to_string(sid_string, group_sid));
- if (!centry) goto do_query;
-
- *num_names = centry_uint32(centry);
-
- if (*num_names == 0) goto do_cached;
-
- (*sid_mem) = talloc(mem_ctx, sizeof(**sid_mem) * (*num_names));
- (*names) = talloc(mem_ctx, sizeof(**names) * (*num_names));
- (*name_types) = talloc(mem_ctx, sizeof(**name_types) * (*num_names));
-
- if (! (*sid_mem) || ! (*names) || ! (*name_types)) {
- smb_panic("lookup_groupmem out of memory");
- }
-
- for (i=0; i<(*num_names); i++) {
- (*sid_mem)[i] = centry_sid(centry, mem_ctx);
- (*names)[i] = centry_string(centry, mem_ctx);
- (*name_types)[i] = centry_uint32(centry);
- }
-
-do_cached:
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- (*num_names) = 0;
- (*sid_mem) = NULL;
- (*names) = NULL;
- (*name_types) = NULL;
-
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->lookup_groupmem(domain, mem_ctx, group_sid, num_names,
- sid_mem, names, name_types);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- centry = centry_start(domain, status);
- if (!centry) goto skip_save;
- centry_put_uint32(centry, *num_names);
- for (i=0; i<(*num_names); i++) {
- centry_put_sid(centry, (*sid_mem)[i]);
- centry_put_string(centry, (*names)[i]);
- centry_put_uint32(centry, (*name_types)[i]);
- }
- centry_end(centry, "GM/%s", sid_to_string(sid_string, group_sid));
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-/* find the sequence number for a domain */
-static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
-{
- refresh_sequence_number(domain, False);
-
- *seq = domain->sequence_number;
-
- return NT_STATUS_OK;
-}
-
-/* enumerate trusted domains */
-static NTSTATUS trusted_domains(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_domains,
- char ***names,
- char ***alt_names,
- DOM_SID **dom_sids)
-{
- struct winbind_cache *cache = get_cache(domain);
-
- /* we don't cache this call */
- return cache->backend->trusted_domains(domain, mem_ctx, num_domains,
- names, alt_names, dom_sids);
-}
-
-/* find the domain sid */
-static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
-{
- struct winbind_cache *cache = get_cache(domain);
-
- /* we don't cache this call */
- return cache->backend->domain_sid(domain, sid);
-}
-
-/* find the alternate names for the domain, if any */
-static NTSTATUS alternate_name(struct winbindd_domain *domain)
-{
- struct winbind_cache *cache = get_cache(domain);
-
- /* we don't cache this call */
- return cache->backend->alternate_name(domain);
-}
-
-/* the ADS backend methods are exposed via this structure */
-struct winbindd_methods cache_methods = {
- True,
- query_user_list,
- enum_dom_groups,
- enum_local_groups,
- name_to_sid,
- sid_to_name,
- query_user,
- lookup_usergroups,
- lookup_groupmem,
- sequence_number,
- trusted_domains,
- domain_sid,
- alternate_name
-};
diff --git a/source4/nsswitch/winbindd_cm.c b/source4/nsswitch/winbindd_cm.c
deleted file mode 100644
index 0748a1c534..0000000000
--- a/source4/nsswitch/winbindd_cm.c
+++ /dev/null
@@ -1,954 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon connection manager
-
- Copyright (C) Tim Potter 2001
- Copyright (C) Andrew Bartlett 2002
-
- 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.
-*/
-
-/*
- We need to manage connections to domain controllers without having to
- mess up the main winbindd code with other issues. The aim of the
- connection manager is to:
-
- - make connections to domain controllers and cache them
- - re-establish connections when networks or servers go down
- - centralise the policy on connection timeouts, domain controller
- selection etc
- - manage re-entrancy for when winbindd becomes able to handle
- multiple outstanding rpc requests
-
- Why not have connection management as part of the rpc layer like tng?
- Good question. This code may morph into libsmb/rpc_cache.c or something
- like that but at the moment it's simply staying as part of winbind. I
- think the TNG architecture of forcing every user of the rpc layer to use
- the connection caching system is a bad idea. It should be an optional
- method of using the routines.
-
- The TNG design is quite good but I disagree with some aspects of the
- implementation. -tpot
-
- */
-
-/*
- TODO:
-
- - I'm pretty annoyed by all the make_nmb_name() stuff. It should be
- moved down into another function.
-
- - There needs to be a utility function in libsmb/namequery.c that does
- cm_get_dc_name()
-
- - Take care when destroying cli_structs as they can be shared between
- various sam handles.
-
- */
-
-#include "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/* Global list of connections. Initially a DLIST but can become a hash
- table or whatever later. */
-
-struct winbindd_cm_conn {
- struct winbindd_cm_conn *prev, *next;
- fstring domain;
- fstring controller;
- fstring pipe_name;
- size_t mutex_ref_count;
- struct cli_state *cli;
- POLICY_HND pol;
-};
-
-static struct winbindd_cm_conn *cm_conns = NULL;
-
-/* Get a domain controller name. Cache positive and negative lookups so we
- don't go to the network too often when something is badly broken. */
-
-#define GET_DC_NAME_CACHE_TIMEOUT 30 /* Seconds between dc lookups */
-
-struct get_dc_name_cache {
- fstring domain_name;
- fstring srv_name;
- time_t lookup_time;
- struct get_dc_name_cache *prev, *next;
-};
-
-/*
- find the DC for a domain using methods appropriate for a ADS domain
-*/
-static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
-{
- ADS_STRUCT *ads;
- const char *realm = domain;
-
- if (strcasecmp(realm, lp_workgroup()) == 0)
- realm = lp_realm();
-
- ads = ads_init(realm, domain, NULL);
- if (!ads)
- return False;
-
- /* we don't need to bind, just connect */
- ads->auth.flags |= ADS_AUTH_NO_BIND;
-
- DEBUG(4,("cm_ads_find_dc: domain=%s\n", domain));
-
-#ifdef HAVE_ADS
- /* a full ads_connect() is actually overkill, as we don't srictly need
- to do the SASL auth in order to get the info we need, but libads
- doesn't offer a better way right now */
- ads_connect(ads);
-#endif
-
- if (!ads->config.realm)
- return False;
-
- fstrcpy(srv_name, ads->config.ldap_server_name);
- strupper(srv_name);
- *dc_ip = ads->ldap_ip;
- ads_destroy(&ads);
-
- DEBUG(4,("cm_ads_find_dc: using server='%s' IP=%s\n",
- srv_name, inet_ntoa(*dc_ip)));
-
- return True;
-}
-
-
-
-static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
-{
- static struct get_dc_name_cache *get_dc_name_cache;
- struct get_dc_name_cache *dcc;
- struct in_addr dc_ip;
- BOOL ret;
-
- /* Check the cache for previous lookups */
-
- for (dcc = get_dc_name_cache; dcc; dcc = dcc->next) {
-
- if (!strequal(domain, dcc->domain_name))
- continue; /* Not our domain */
-
- if ((time(NULL) - dcc->lookup_time) >
- GET_DC_NAME_CACHE_TIMEOUT) {
-
- /* Cache entry has expired, delete it */
-
- DEBUG(10, ("get_dc_name_cache entry expired for %s\n", domain));
-
- DLIST_REMOVE(get_dc_name_cache, dcc);
- SAFE_FREE(dcc);
-
- break;
- }
-
- /* Return a positive or negative lookup for this domain */
-
- if (dcc->srv_name[0]) {
- DEBUG(10, ("returning positive get_dc_name_cache entry for %s\n", domain));
- fstrcpy(srv_name, dcc->srv_name);
- return True;
- } else {
- DEBUG(10, ("returning negative get_dc_name_cache entry for %s\n", domain));
- return False;
- }
- }
-
- /* Add cache entry for this lookup. */
-
- DEBUG(10, ("Creating get_dc_name_cache entry for %s\n", domain));
-
- if (!(dcc = (struct get_dc_name_cache *)
- malloc(sizeof(struct get_dc_name_cache))))
- return False;
-
- ZERO_STRUCTP(dcc);
-
- fstrcpy(dcc->domain_name, domain);
- dcc->lookup_time = time(NULL);
-
- DLIST_ADD(get_dc_name_cache, dcc);
-
- zero_ip(&dc_ip);
-
- ret = False;
- if (lp_security() == SEC_ADS)
- ret = cm_ads_find_dc(domain, &dc_ip, srv_name);
-
- if (!ret) {
- /* fall back on rpc methods if the ADS methods fail */
- ret = rpc_find_dc(domain, srv_name, &dc_ip);
- }
-
- if (!ret)
- return False;
-
- /* We have a name so make the cache entry positive now */
- fstrcpy(dcc->srv_name, srv_name);
-
- DEBUG(3, ("cm_get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
- inet_ntoa(dc_ip), domain));
-
- *ip_out = dc_ip;
-
- return True;
-}
-
-/* Choose between anonymous or authenticated connections. We need to use
- an authenticated connection if DCs have the RestrictAnonymous registry
- entry set > 0, or the "Additional restrictions for anonymous
- connections" set in the win2k Local Security Policy.
-
- Caller to free() result in domain, username, password
-*/
-
-static void cm_get_ipc_userpass(char **username, char **domain, char **password)
-{
- *username = secrets_fetch(SECRETS_AUTH_USER, NULL);
- *domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
- *password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
-
- if (*username && **username) {
-
- if (!*domain || !**domain)
- *domain = smb_xstrdup(lp_workgroup());
-
- if (!*password || !**password)
- *password = smb_xstrdup("");
-
- DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
- *domain, *username));
-
- } else {
- DEBUG(3, ("IPC$ connections done anonymously\n"));
- *username = smb_xstrdup("");
- *domain = smb_xstrdup("");
- *password = smb_xstrdup("");
- }
-}
-
-/* Open a new smb pipe connection to a DC on a given domain. Cache
- negative creation attempts so we don't try and connect to broken
- machines too often. */
-
-#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */
-
-struct failed_connection_cache {
- fstring domain_name;
- fstring controller;
- time_t lookup_time;
- NTSTATUS nt_status;
- struct failed_connection_cache *prev, *next;
-};
-
-static struct failed_connection_cache *failed_connection_cache;
-
-/* Add an entry to the failed conneciton cache */
-
-static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn,
- NTSTATUS result)
-{
- struct failed_connection_cache *fcc;
-
- SMB_ASSERT(!NT_STATUS_IS_OK(result));
-
- /* Check we already aren't in the cache */
-
- for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
- if (strequal(fcc->domain_name, new_conn->domain)) {
- DEBUG(10, ("domain %s already tried and failed\n",
- fcc->domain_name));
- return;
- }
- }
-
- /* Create negative lookup cache entry for this domain and controller */
-
- if (!(fcc = (struct failed_connection_cache *)
- malloc(sizeof(struct failed_connection_cache)))) {
- DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
- return;
- }
-
- ZERO_STRUCTP(fcc);
-
- fstrcpy(fcc->domain_name, new_conn->domain);
- fstrcpy(fcc->controller, new_conn->controller);
- fcc->lookup_time = time(NULL);
- fcc->nt_status = result;
-
- DLIST_ADD(failed_connection_cache, fcc);
-}
-
-/* Open a connction to the remote server, cache failures for 30 seconds */
-
-static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
- struct winbindd_cm_conn *new_conn, BOOL keep_mutex)
-{
- struct failed_connection_cache *fcc;
- NTSTATUS result;
- char *ipc_username, *ipc_domain, *ipc_password;
- struct in_addr dc_ip;
- int i;
- BOOL retry = True;
- BOOL got_mutex = False;
-
- ZERO_STRUCT(dc_ip);
-
- fstrcpy(new_conn->domain, domain);
- fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));
-
- /* Look for a domain controller for this domain. Negative results
- are cached so don't bother applying the caching for this
- function just yet. */
-
- if (!cm_get_dc_name(domain, new_conn->controller, &dc_ip)) {
- result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- add_failed_connection_entry(new_conn, result);
- return result;
- }
-
- /* Return false if we have tried to look up this domain and netbios
- name before and failed. */
-
- for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
-
- if (!(strequal(domain, fcc->domain_name) &&
- strequal(new_conn->controller, fcc->controller)))
- continue; /* Not our domain */
-
- if ((time(NULL) - fcc->lookup_time) >
- FAILED_CONNECTION_CACHE_TIMEOUT) {
-
- /* Cache entry has expired, delete it */
-
- DEBUG(10, ("cm_open_connection cache entry expired for %s, %s\n", domain, new_conn->controller));
-
- DLIST_REMOVE(failed_connection_cache, fcc);
- free(fcc);
-
- break;
- }
-
- /* The timeout hasn't expired yet so return false */
-
- DEBUG(10, ("returning negative open_connection_cache entry for %s, %s\n", domain, new_conn->controller));
-
- result = fcc->nt_status;
- SMB_ASSERT(!NT_STATUS_IS_OK(result));
- return result;
- }
-
- /* Initialise SMB connection */
-
- cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
-
- DEBUG(5, ("connecting to %s from %s with username [%s]\\[%s]\n",
- new_conn->controller, lp_netbios_name(), ipc_domain, ipc_username));
-
- for (i = 0; retry && (i < 3); i++) {
-
- if (!secrets_named_mutex(new_conn->controller, WINBIND_SERVER_MUTEX_WAIT_TIME, &new_conn->mutex_ref_count)) {
- DEBUG(0,("cm_open_connection: mutex grab failed for %s\n", new_conn->controller));
- result = NT_STATUS_POSSIBLE_DEADLOCK;
- continue;
- }
-
- got_mutex = True;
-
- result = cli_full_connection(&new_conn->cli, lp_netbios_name(), new_conn->controller,
- &dc_ip, 0, "IPC$", "IPC", ipc_username, ipc_domain,
- ipc_password, 0, &retry);
-
- if (NT_STATUS_IS_OK(result))
- break;
-
- secrets_named_mutex_release(new_conn->controller, &new_conn->mutex_ref_count);
- got_mutex = False;
- }
-
- SAFE_FREE(ipc_username);
- SAFE_FREE(ipc_domain);
- SAFE_FREE(ipc_password);
-
- if (!NT_STATUS_IS_OK(result)) {
- if (got_mutex)
- secrets_named_mutex_release(new_conn->controller, &new_conn->mutex_ref_count);
- add_failed_connection_entry(new_conn, result);
- return result;
- }
-
- if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) {
- result = NT_STATUS_PIPE_NOT_AVAILABLE;
- /*
- * only cache a failure if we are not trying to open the
- * **win2k** specific lsarpc UUID. This could be an NT PDC
- * and therefore a failure is normal. This should probably
- * be abstracted to a check for 2k specific pipes and wondering
- * if the PDC is an NT4 box. but since there is only one 2k
- * specific UUID right now, i'm not going to bother. --jerry
- */
- if (got_mutex)
- secrets_named_mutex_release(new_conn->controller, &new_conn->mutex_ref_count);
- if ( !is_win2k_pipe(pipe_index) )
- add_failed_connection_entry(new_conn, result);
- cli_shutdown(new_conn->cli);
- return result;
- }
-
- if ((got_mutex) && !keep_mutex)
- secrets_named_mutex_release(new_conn->controller, &new_conn->mutex_ref_count);
- return NT_STATUS_OK;
-}
-
-/* Return true if a connection is still alive */
-
-static BOOL connection_ok(struct winbindd_cm_conn *conn)
-{
- if (!conn) {
- smb_panic("Invalid paramater passed to conneciton_ok(): conn was NULL!\n");
- return False;
- }
-
- if (!conn->cli) {
- DEBUG(0, ("Connection to %s for domain %s (pipe %s) has NULL conn->cli!\n",
- conn->controller, conn->domain, conn->pipe_name));
- smb_panic("connection_ok: conn->cli was null!");
- return False;
- }
-
- if (!conn->cli->initialised) {
- DEBUG(0, ("Connection to %s for domain %s (pipe %s) was never initialised!\n",
- conn->controller, conn->domain, conn->pipe_name));
- smb_panic("connection_ok: conn->cli->initialised is False!");
- return False;
- }
-
- if (conn->cli->fd == -1) {
- DEBUG(3, ("Connection to %s for domain %s (pipe %s) has died or was never started (fd == -1)\n",
- conn->controller, conn->domain, conn->pipe_name));
- return False;
- }
-
- return True;
-}
-
-/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */
-
-static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_name,
- struct winbindd_cm_conn **conn_out, BOOL keep_mutex)
-{
- struct winbindd_cm_conn *conn, conn_temp;
- NTSTATUS result;
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, pipe_name)) {
- if (!connection_ok(conn)) {
- if (conn->cli)
- cli_shutdown(conn->cli);
- ZERO_STRUCT(conn_temp);
- conn_temp.next = conn->next;
- DLIST_REMOVE(cm_conns, conn);
- SAFE_FREE(conn);
- conn = &conn_temp; /* Just to keep the loop moving */
- } else {
- if (keep_mutex) {
- if (!secrets_named_mutex(conn->controller,
- WINBIND_SERVER_MUTEX_WAIT_TIME, &conn->mutex_ref_count))
- DEBUG(0,("get_connection_from_cache: mutex grab failed for %s\n",
- conn->controller));
- }
- break;
- }
- }
- }
-
- if (!conn) {
- if (!(conn = malloc(sizeof(*conn))))
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP(conn);
-
- if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, get_pipe_index(pipe_name), conn, keep_mutex))) {
- DEBUG(3, ("Could not open a connection to %s for %s (%s)\n",
- domain, pipe_name, nt_errstr(result)));
- SAFE_FREE(conn);
- return result;
- }
- DLIST_ADD(cm_conns, conn);
- }
-
- *conn_out = conn;
- return NT_STATUS_OK;
-}
-
-
-/**********************************************************************************
-**********************************************************************************/
-
-BOOL cm_check_for_native_mode_win2k( const char *domain )
-{
- NTSTATUS result;
- struct winbindd_cm_conn conn;
- DS_DOMINFO_CTR ctr;
- BOOL ret = False;
-
- ZERO_STRUCT( conn );
- ZERO_STRUCT( ctr );
-
-
- if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn, False)) ) {
- DEBUG(5, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n",
- domain, nt_errstr(result)));
- return False;
- }
-
- if ( conn.cli ) {
- if ( !NT_STATUS_IS_OK(cli_ds_getprimarydominfo( conn.cli,
- conn.cli->mem_ctx, DsRolePrimaryDomainInfoBasic, &ctr)) ) {
- ret = False;
- goto done;
- }
- }
-
- if ( (ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING)
- && !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
- ret = True;
-
-done:
- if ( conn.cli )
- cli_shutdown( conn.cli );
-
- return ret;
-}
-
-
-
-/* Return a LSA policy handle on a domain */
-
-CLI_POLICY_HND *cm_get_lsa_handle(const char *domain)
-{
- struct winbindd_cm_conn *conn;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- NTSTATUS result;
- static CLI_POLICY_HND hnd;
-
- /* Look for existing connections */
-
- if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_LSARPC, &conn, False)))
- return NULL;
-
- /* This *shitty* code needs scrapping ! JRA */
- if (policy_handle_is_valid(&conn->pol)) {
- hnd.pol = conn->pol;
- hnd.cli = conn->cli;
- return &hnd;
- }
-
- result = cli_lsa_open_policy(conn->cli, conn->cli->mem_ctx, False,
- des_access, &conn->pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- /* Hit the cache code again. This cleans out the old connection and gets a new one */
- if (conn->cli->fd == -1) { /* Try again, if the remote host disapeared */
- if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_LSARPC, &conn, False)))
- return NULL;
-
- result = cli_lsa_open_policy(conn->cli, conn->cli->mem_ctx, False,
- des_access, &conn->pol);
- }
-
- if (!NT_STATUS_IS_OK(result)) {
- cli_shutdown(conn->cli);
- DLIST_REMOVE(cm_conns, conn);
- SAFE_FREE(conn);
- return NULL;
- }
- }
-
- hnd.pol = conn->pol;
- hnd.cli = conn->cli;
-
- return &hnd;
-}
-
-/* Return a SAM policy handle on a domain */
-
-CLI_POLICY_HND *cm_get_sam_handle(char *domain)
-{
- struct winbindd_cm_conn *conn;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- NTSTATUS result;
- static CLI_POLICY_HND hnd;
-
- /* Look for existing connections */
-
- if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_SAMR, &conn, False)))
- return NULL;
-
- /* This *shitty* code needs scrapping ! JRA */
- if (policy_handle_is_valid(&conn->pol)) {
- hnd.pol = conn->pol;
- hnd.cli = conn->cli;
- return &hnd;
- }
- result = cli_samr_connect(conn->cli, conn->cli->mem_ctx,
- des_access, &conn->pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- /* Hit the cache code again. This cleans out the old connection and gets a new one */
- if (conn->cli->fd == -1) { /* Try again, if the remote host disapeared */
- if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_SAMR, &conn, False)))
- return NULL;
-
- result = cli_samr_connect(conn->cli, conn->cli->mem_ctx,
- des_access, &conn->pol);
- }
-
- if (!NT_STATUS_IS_OK(result)) {
- cli_shutdown(conn->cli);
- DLIST_REMOVE(cm_conns, conn);
- SAFE_FREE(conn);
- return NULL;
- }
- }
-
- hnd.pol = conn->pol;
- hnd.cli = conn->cli;
-
- return &hnd;
-}
-
-#if 0 /* This code now *well* out of date */
-
-/* Return a SAM domain policy handle on a domain */
-
-CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid)
-{
- struct winbindd_cm_conn *conn, *basic_conn = NULL;
- static CLI_POLICY_HND hnd;
- NTSTATUS result;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
-
- /* Look for existing connections */
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM) {
-
- if (!connection_ok(conn)) {
- /* Shutdown cli? Free conn? Allow retry of DC? */
- DLIST_REMOVE(cm_conns, conn);
- return NULL;
- }
-
- goto ok;
- }
- }
-
- /* Create a basic handle to open a domain handle from */
-
- if (!cm_get_sam_handle(domain))
- return False;
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_BASIC)
- basic_conn = conn;
- }
-
- if (!(conn = (struct winbindd_cm_conn *)
- malloc(sizeof(struct winbindd_cm_conn))))
- return NULL;
-
- ZERO_STRUCTP(conn);
-
- fstrcpy(conn->domain, basic_conn->domain);
- fstrcpy(conn->controller, basic_conn->controller);
- fstrcpy(conn->pipe_name, basic_conn->pipe_name);
-
- conn->pipe_data.samr.pipe_type = SAM_PIPE_DOM;
- conn->cli = basic_conn->cli;
-
- result = cli_samr_open_domain(conn->cli, conn->cli->mem_ctx,
- &basic_conn->pol, des_access,
- domain_sid, &conn->pol);
-
- if (!NT_STATUS_IS_OK(result))
- return NULL;
-
- /* Add to list */
-
- DLIST_ADD(cm_conns, conn);
-
- ok:
- hnd.pol = conn->pol;
- hnd.cli = conn->cli;
-
- return &hnd;
-}
-
-/* Return a SAM policy handle on a domain user */
-
-CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid,
- uint32 user_rid)
-{
- struct winbindd_cm_conn *conn, *basic_conn = NULL;
- static CLI_POLICY_HND hnd;
- NTSTATUS result;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
-
- /* Look for existing connections */
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_USER &&
- conn->pipe_data.samr.rid == user_rid) {
-
- if (!connection_ok(conn)) {
- /* Shutdown cli? Free conn? Allow retry of DC? */
- DLIST_REMOVE(cm_conns, conn);
- return NULL;
- }
-
- goto ok;
- }
- }
-
- /* Create a domain handle to open a user handle from */
-
- if (!cm_get_sam_dom_handle(domain, domain_sid))
- return NULL;
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM)
- basic_conn = conn;
- }
-
- if (!basic_conn) {
- DEBUG(0, ("No domain sam handle was created!\n"));
- return NULL;
- }
-
- if (!(conn = (struct winbindd_cm_conn *)
- malloc(sizeof(struct winbindd_cm_conn))))
- return NULL;
-
- ZERO_STRUCTP(conn);
-
- fstrcpy(conn->domain, basic_conn->domain);
- fstrcpy(conn->controller, basic_conn->controller);
- fstrcpy(conn->pipe_name, basic_conn->pipe_name);
-
- conn->pipe_data.samr.pipe_type = SAM_PIPE_USER;
- conn->cli = basic_conn->cli;
- conn->pipe_data.samr.rid = user_rid;
-
- result = cli_samr_open_user(conn->cli, conn->cli->mem_ctx,
- &basic_conn->pol, des_access, user_rid,
- &conn->pol);
-
- if (!NT_STATUS_IS_OK(result))
- return NULL;
-
- /* Add to list */
-
- DLIST_ADD(cm_conns, conn);
-
- ok:
- hnd.pol = conn->pol;
- hnd.cli = conn->cli;
-
- return &hnd;
-}
-
-/* Return a SAM policy handle on a domain group */
-
-CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid,
- uint32 group_rid)
-{
- struct winbindd_cm_conn *conn, *basic_conn = NULL;
- static CLI_POLICY_HND hnd;
- NTSTATUS result;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
-
- /* Look for existing connections */
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_GROUP &&
- conn->pipe_data.samr.rid == group_rid) {
-
- if (!connection_ok(conn)) {
- /* Shutdown cli? Free conn? Allow retry of DC? */
- DLIST_REMOVE(cm_conns, conn);
- return NULL;
- }
-
- goto ok;
- }
- }
-
- /* Create a domain handle to open a user handle from */
-
- if (!cm_get_sam_dom_handle(domain, domain_sid))
- return NULL;
-
- for (conn = cm_conns; conn; conn = conn->next) {
- if (strequal(conn->domain, domain) &&
- strequal(conn->pipe_name, PIPE_SAMR) &&
- conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM)
- basic_conn = conn;
- }
-
- if (!basic_conn) {
- DEBUG(0, ("No domain sam handle was created!\n"));
- return NULL;
- }
-
- if (!(conn = (struct winbindd_cm_conn *)
- malloc(sizeof(struct winbindd_cm_conn))))
- return NULL;
-
- ZERO_STRUCTP(conn);
-
- fstrcpy(conn->domain, basic_conn->domain);
- fstrcpy(conn->controller, basic_conn->controller);
- fstrcpy(conn->pipe_name, basic_conn->pipe_name);
-
- conn->pipe_data.samr.pipe_type = SAM_PIPE_GROUP;
- conn->cli = basic_conn->cli;
- conn->pipe_data.samr.rid = group_rid;
-
- result = cli_samr_open_group(conn->cli, conn->cli->mem_ctx,
- &basic_conn->pol, des_access, group_rid,
- &conn->pol);
-
- if (!NT_STATUS_IS_OK(result))
- return NULL;
-
- /* Add to list */
-
- DLIST_ADD(cm_conns, conn);
-
- ok:
- hnd.pol = conn->pol;
- hnd.cli = conn->cli;
-
- return &hnd;
-}
-
-#endif
-
-/* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the
- netlogon pipe as no handle is returned. */
-
-NTSTATUS cm_get_netlogon_cli(const char *domain, const unsigned char *trust_passwd,
- struct cli_state **cli)
-{
- NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- struct winbindd_cm_conn *conn;
- uint32 neg_flags = 0x000001ff;
-
- if (!cli)
- return NT_STATUS_INVALID_PARAMETER;
-
- /* Open an initial conection - keep the mutex. */
-
- if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_NETLOGON, &conn, True)))
- return result;
-
- result = cli_nt_setup_creds(conn->cli, get_sec_chan(), trust_passwd, &neg_flags, 2);
-
- if (conn->mutex_ref_count)
- secrets_named_mutex_release(conn->controller, &conn->mutex_ref_count);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0, ("error connecting to domain password server: %s\n",
- nt_errstr(result)));
-
- /* Hit the cache code again. This cleans out the old connection and gets a new one */
- if (conn->cli->fd == -1) {
-
- if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_NETLOGON, &conn, True)))
- return result;
-
- /* Try again */
- result = cli_nt_setup_creds( conn->cli, get_sec_chan(),trust_passwd, &neg_flags, 2);
-
- if (conn->mutex_ref_count)
- secrets_named_mutex_release(conn->controller, &conn->mutex_ref_count);
- }
-
- if (!NT_STATUS_IS_OK(result)) {
- cli_shutdown(conn->cli);
- DLIST_REMOVE(cm_conns, conn);
- SAFE_FREE(conn);
- return result;
- }
- }
-
- *cli = conn->cli;
-
- return result;
-}
-
-/* Dump the current connection status */
-
-static void dump_conn_list(void)
-{
- struct winbindd_cm_conn *con;
-
- DEBUG(0, ("\tDomain Controller Pipe\n"));
-
- for(con = cm_conns; con; con = con->next) {
- char *msg;
-
- /* Display pipe info */
-
- if (asprintf(&msg, "\t%-15s %-15s %-16s", con->domain, con->controller, con->pipe_name) < 0) {
- DEBUG(0, ("Error: not enough memory!\n"));
- } else {
- DEBUG(0, ("%s\n", msg));
- SAFE_FREE(msg);
- }
- }
-}
-
-void winbindd_cm_status(void)
-{
- /* List open connections */
-
- DEBUG(0, ("winbindd connection manager status:\n"));
-
- if (cm_conns)
- dump_conn_list();
- else
- DEBUG(0, ("\tNo active connections\n"));
-}
diff --git a/source4/nsswitch/winbindd_dual.c b/source4/nsswitch/winbindd_dual.c
deleted file mode 100644
index 207757bcea..0000000000
--- a/source4/nsswitch/winbindd_dual.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind background daemon
-
- Copyright (C) Andrew Tridgell 2002
-
- 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.
-*/
-
-/*
- the idea of the optional dual daemon mode is ot prevent slow domain
- responses from clagging up the rest of the system. When in dual
- daemon mode winbindd always responds to requests from cache if the
- request is in cache, and if the cached answer is stale then it asks
- the "dual daemon" to update the cache for that request
-
- */
-
-#include "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-extern BOOL opt_dual_daemon;
-BOOL background_process = False;
-int dual_daemon_pipe = -1;
-
-
-/* a list of requests ready to be sent to the dual daemon */
-struct dual_list {
- struct dual_list *next;
- char *data;
- int length;
- int offset;
-};
-
-static struct dual_list *dual_list;
-static struct dual_list *dual_list_end;
-
-/*
- setup a select() including the dual daemon pipe
- */
-int dual_select_setup(fd_set *fds, int maxfd)
-{
- if (dual_daemon_pipe == -1 ||
- !dual_list) {
- return maxfd;
- }
-
- FD_SET(dual_daemon_pipe, fds);
- if (dual_daemon_pipe > maxfd) {
- maxfd = dual_daemon_pipe;
- }
- return maxfd;
-}
-
-
-/*
- a hook called from the main winbindd select() loop to handle writes
- to the dual daemon pipe
-*/
-void dual_select(fd_set *fds)
-{
- int n;
-
- if (dual_daemon_pipe == -1 ||
- !dual_list ||
- !FD_ISSET(dual_daemon_pipe, fds)) {
- return;
- }
-
- n = sys_write(dual_daemon_pipe,
- &dual_list->data[dual_list->offset],
- dual_list->length - dual_list->offset);
-
- if (n <= 0) {
- /* the pipe is dead! fall back to normal operation */
- dual_daemon_pipe = -1;
- return;
- }
-
- dual_list->offset += n;
-
- if (dual_list->offset == dual_list->length) {
- struct dual_list *next;
- next = dual_list->next;
- free(dual_list->data);
- free(dual_list);
- dual_list = next;
- if (!dual_list) {
- dual_list_end = NULL;
- }
- }
-}
-
-/*
- send a request to the background daemon
- this is called for stale cached entries
-*/
-void dual_send_request(struct winbindd_cli_state *state)
-{
- struct dual_list *list;
-
- if (!background_process) return;
-
- list = malloc(sizeof(*list));
- if (!list) return;
-
- list->next = NULL;
- list->data = memdup(&state->request, sizeof(state->request));
- list->length = sizeof(state->request);
- list->offset = 0;
-
- if (!dual_list_end) {
- dual_list = list;
- dual_list_end = list;
- } else {
- dual_list_end->next = list;
- dual_list_end = list;
- }
-
- background_process = False;
-}
-
-
-/*
-the main dual daemon
-*/
-void do_dual_daemon(void)
-{
- int fdpair[2];
- struct winbindd_cli_state state;
-
- if (pipe(fdpair) != 0) {
- return;
- }
-
- ZERO_STRUCT(state);
- state.pid = getpid();
-
- dual_daemon_pipe = fdpair[1];
- state.sock = fdpair[0];
-
- if (fork() != 0) {
- close(fdpair[0]);
- return;
- }
- close(fdpair[1]);
-
- if (!winbind_setup_common())
- _exit(0);
-
- dual_daemon_pipe = -1;
- opt_dual_daemon = False;
-
- while (1) {
- /* free up any talloc memory */
- lp_talloc_free();
- main_loop_talloc_free();
-
- /* fetch a request from the main daemon */
- winbind_client_read(&state);
-
- if (state.finished) {
- /* we lost contact with our parent */
- exit(0);
- }
-
- /* process full rquests */
- if (state.read_buf_len == sizeof(state.request)) {
- DEBUG(4,("dual daemon request %d\n", (int)state.request.cmd));
-
- /* special handling for the stateful requests */
- switch (state.request.cmd) {
- case WINBINDD_GETPWENT:
- winbindd_setpwent(&state);
- break;
-
- case WINBINDD_GETGRENT:
- case WINBINDD_GETGRLST:
- winbindd_setgrent(&state);
- break;
- default:
- break;
- }
-
- winbind_process_packet(&state);
- SAFE_FREE(state.response.extra_data);
-
- free_getent_state(state.getpwent_state);
- free_getent_state(state.getgrent_state);
- state.getpwent_state = NULL;
- state.getgrent_state = NULL;
- }
- }
-}
-
diff --git a/source4/nsswitch/winbindd_group.c b/source4/nsswitch/winbindd_group.c
deleted file mode 100644
index d06db5943c..0000000000
--- a/source4/nsswitch/winbindd_group.c
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 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 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 "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/***************************************************************
- Empty static struct for negative caching.
-****************************************************************/
-
-/* Fill a grent structure from various other information */
-
-static BOOL fill_grent(struct winbindd_gr *gr, const char *dom_name,
- const char *gr_name, gid_t unix_gid)
-{
- fstring full_group_name;
- /* Fill in uid/gid */
- fill_domain_username(full_group_name, dom_name, gr_name);
-
- gr->gr_gid = unix_gid;
-
- /* Group name and password */
-
- safe_strcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name) - 1);
- safe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1);
-
- return True;
-}
-
-/* Fill in the group membership field of a NT group given by group_sid */
-
-static BOOL fill_grent_mem(struct winbindd_domain *domain,
- DOM_SID *group_sid,
- enum SID_NAME_USE group_name_type,
- int *num_gr_mem, char **gr_mem, int *gr_mem_len)
-{
- DOM_SID **sid_mem = NULL;
- uint32 num_names = 0;
- uint32 *name_types = NULL;
- unsigned int buf_len, buf_ndx, i;
- char **names = NULL, *buf;
- BOOL result = False;
- TALLOC_CTX *mem_ctx;
- NTSTATUS status;
- fstring sid_string;
-
- if (!(mem_ctx = talloc_init("fill_grent_mem(%s)", domain->name)))
- return False;
-
- /* Initialise group membership information */
-
- DEBUG(10, ("group SID %s\n", sid_to_string(sid_string, group_sid)));
-
- *num_gr_mem = 0;
-
- if (group_name_type != SID_NAME_DOM_GRP) {
- DEBUG(1, ("SID %s in domain %s isn't a domain group\n",
- sid_to_string(sid_string, group_sid), domain->name));
- goto done;
- }
-
- /* Lookup group members */
- status = domain->methods->lookup_groupmem(domain, mem_ctx, group_sid, &num_names,
- &sid_mem, &names, &name_types);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("could not lookup membership for group rid %s in domain %s (error: %s)\n",
- sid_to_string(sid_string, group_sid), domain->name, nt_errstr(status)));
-
- goto done;
- }
-
- DEBUG(10, ("looked up %d names\n", num_names));
-
- if (DEBUGLEVEL >= 10) {
- for (i = 0; i < num_names; i++)
- DEBUG(10, ("\t%20s %s %d\n", names[i], sid_to_string(sid_string, sid_mem[i]),
- name_types[i]));
- }
-
- /* Add members to list */
-
- buf = NULL;
- buf_len = buf_ndx = 0;
-
- again:
-
- for (i = 0; i < num_names; i++) {
- char *the_name;
- fstring name;
- int len;
-
- the_name = names[i];
-
- DEBUG(10, ("processing name %s\n", the_name));
-
- /* FIXME: need to cope with groups within groups. These
- occur in Universal groups on a Windows 2000 native mode
- server. */
-
- if (name_types[i] != SID_NAME_USER) {
- DEBUG(3, ("name %s isn't a domain user\n", the_name));
- continue;
- }
-
- /* Don't bother with machine accounts */
-
- if (the_name[strlen(the_name) - 1] == '$') {
- DEBUG(10, ("%s is machine account\n", the_name));
- continue;
- }
-
- /* Append domain name */
-
- fill_domain_username(name, domain->name, the_name);
-
- len = strlen(name);
-
- /* Add to list or calculate buffer length */
-
- if (!buf) {
- buf_len += len + 1; /* List is comma separated */
- (*num_gr_mem)++;
- DEBUG(10, ("buf_len + %d = %d\n", len + 1, buf_len));
- } else {
- DEBUG(10, ("appending %s at ndx %d\n", name, len));
- safe_strcpy(&buf[buf_ndx], name, len);
- buf_ndx += len;
- buf[buf_ndx] = ',';
- buf_ndx++;
- }
- }
-
- /* Allocate buffer */
-
- if (!buf && buf_len != 0) {
- if (!(buf = malloc(buf_len))) {
- DEBUG(1, ("out of memory\n"));
- result = False;
- goto done;
- }
- memset(buf, 0, buf_len);
- goto again;
- }
-
- if (buf && buf_ndx > 0) {
- buf[buf_ndx - 1] = '\0';
- }
-
- *gr_mem = buf;
- *gr_mem_len = buf_len;
-
- DEBUG(10, ("num_mem = %d, len = %d, mem = %s\n", *num_gr_mem,
- buf_len, *num_gr_mem ? buf : "NULL"));
- result = True;
-
-done:
-
- talloc_destroy(mem_ctx);
-
- DEBUG(10, ("fill_grent_mem returning %d\n", result));
-
- return result;
-}
-
-/* Return a group structure from a group name */
-
-enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
-{
- DOM_SID group_sid;
- struct winbindd_domain *domain;
- enum SID_NAME_USE name_type;
- fstring name_domain, name_group;
- char *tmp, *gr_mem;
- gid_t gid;
- int gr_mem_len;
-
- /* Ensure null termination */
- state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';
-
- DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid,
- state->request.data.groupname));
-
- /* Parse domain and groupname */
-
- memset(name_group, 0, sizeof(fstring));
-
- tmp = state->request.data.groupname;
- if (!parse_domain_user(tmp, name_domain, name_group))
- return WINBINDD_ERROR;
-
- /* Get info for the domain */
-
- if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(0, ("could not get domain sid for domain %s\n",
- name_domain));
- return WINBINDD_ERROR;
- }
-
- /* Get rid and name type from name */
-
- if (!winbindd_lookup_sid_by_name(domain, name_group, &group_sid,
- &name_type)) {
- DEBUG(1, ("group %s in domain %s does not exist\n",
- name_group, name_domain));
- return WINBINDD_ERROR;
- }
-
- if ((name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_DOM_GRP)) {
- DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
- name_group, name_type));
- return WINBINDD_ERROR;
- }
-
- if (!winbindd_idmap_get_gid_from_sid(&group_sid, &gid)) {
- DEBUG(1, ("error converting unix gid to sid\n"));
- return WINBINDD_ERROR;
- }
-
- if (!fill_grent(&state->response.data.gr, name_domain,
- name_group, gid) ||
- !fill_grent_mem(domain, &group_sid, name_type,
- &state->response.data.gr.num_gr_mem,
- &gr_mem, &gr_mem_len)) {
- return WINBINDD_ERROR;
- }
-
- /* Group membership lives at start of extra data */
-
- state->response.data.gr.gr_mem_ofs = 0;
-
- state->response.length += gr_mem_len;
- state->response.extra_data = gr_mem;
-
- return WINBINDD_OK;
-}
-
-/* Return a group structure from a gid number */
-
-enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
-{
- struct winbindd_domain *domain;
- DOM_SID group_sid;
- enum SID_NAME_USE name_type;
- fstring dom_name;
- fstring group_name;
- int gr_mem_len;
- char *gr_mem;
-
- DEBUG(3, ("[%5d]: getgrgid %d\n", state->pid,
- state->request.data.gid));
-
- /* Bug out if the gid isn't in the winbind range */
-
- if ((state->request.data.gid < server_state.gid_low) ||
- (state->request.data.gid > server_state.gid_high))
- return WINBINDD_ERROR;
-
- /* Get rid from gid */
-
- if (!winbindd_idmap_get_sid_from_gid(state->request.data.gid, &group_sid)) {
- DEBUG(1, ("could not convert gid %d to rid\n",
- state->request.data.gid));
- return WINBINDD_ERROR;
- }
-
- /* Get name from sid */
-
- if (!winbindd_lookup_name_by_sid(&group_sid, dom_name, group_name, &name_type)) {
- DEBUG(1, ("could not lookup sid\n"));
- return WINBINDD_ERROR;
- }
-
- if (!((name_type == SID_NAME_ALIAS) ||
- (name_type == SID_NAME_DOM_GRP))) {
- DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
- group_name, name_type));
- return WINBINDD_ERROR;
- }
-
- /* Fill in group structure */
-
- domain = find_domain_from_sid(&group_sid);
-
- if (!domain) {
- DEBUG(1,("Can't find domain from sid\n"));
- return WINBINDD_ERROR;
- }
-
- if (!fill_grent(&state->response.data.gr, dom_name, group_name,
- state->request.data.gid) ||
- !fill_grent_mem(domain, &group_sid, name_type,
- &state->response.data.gr.num_gr_mem,
- &gr_mem, &gr_mem_len))
- return WINBINDD_ERROR;
-
- /* Group membership lives at start of extra data */
-
- state->response.data.gr.gr_mem_ofs = 0;
-
- state->response.length += gr_mem_len;
- state->response.extra_data = gr_mem;
-
- return WINBINDD_OK;
-}
-
-/*
- * set/get/endgrent functions
- */
-
-/* "Rewind" file pointer for group database enumeration */
-
-enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
-{
- struct winbindd_domain *domain;
-
- DEBUG(3, ("[%5d]: setgrent\n", state->pid));
-
- /* Check user has enabled this */
-
- if (!lp_winbind_enum_groups())
- return WINBINDD_ERROR;
-
- /* Free old static data if it exists */
-
- if (state->getgrent_state != NULL) {
- free_getent_state(state->getgrent_state);
- state->getgrent_state = NULL;
- }
-
- /* Create sam pipes for each domain we know about */
-
- for (domain = domain_list(); domain != NULL; domain = domain->next) {
- struct getent_state *domain_state;
-
- /* Create a state record for this domain */
-
- if ((domain_state = (struct getent_state *)
- malloc(sizeof(struct getent_state))) == NULL) {
- DEBUG(1, ("winbindd_setgrent: malloc failed for domain_state!\n"));
- return WINBINDD_ERROR;
- }
-
- ZERO_STRUCTP(domain_state);
-
- fstrcpy(domain_state->domain_name, domain->name);
-
- /* Add to list of open domains */
-
- DLIST_ADD(state->getgrent_state, domain_state);
- }
-
- return WINBINDD_OK;
-}
-
-/* Close file pointer to ntdom group database */
-
-enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state)
-{
- DEBUG(3, ("[%5d]: endgrent\n", state->pid));
-
- free_getent_state(state->getgrent_state);
- state->getgrent_state = NULL;
-
- return WINBINDD_OK;
-}
-
-/* Get the list of domain groups and domain aliases for a domain. We fill in
- the sam_entries and num_sam_entries fields with domain group information.
- The dispinfo_ndx field is incremented to the index of the next group to
- fetch. Return True if some groups were returned, False otherwise. */
-
-#define MAX_FETCH_SAM_ENTRIES 100
-
-static BOOL get_sam_group_entries(struct getent_state *ent)
-{
- NTSTATUS status;
- uint32 num_entries;
- struct acct_info *name_list = NULL, *tmp_name_list = NULL;
- TALLOC_CTX *mem_ctx;
- BOOL result = False;
- struct acct_info *sam_grp_entries = NULL;
- struct winbindd_domain *domain;
-
- if (ent->got_sam_entries)
- return False;
-
- if (!(mem_ctx = talloc_init("get_sam_group_entries(%s)",
- ent->domain_name))) {
- DEBUG(1, ("get_sam_group_entries: could not create talloc context!\n"));
- return False;
- }
-
- /* Free any existing group info */
-
- SAFE_FREE(ent->sam_entries);
- ent->num_sam_entries = 0;
- ent->got_sam_entries = True;
-
- /* Enumerate domain groups */
-
- num_entries = 0;
-
- if (!(domain = find_domain_from_name(ent->domain_name))) {
- DEBUG(3, ("no such domain %s in get_sam_group_entries\n", ent->domain_name));
- goto done;
- }
-
- /* always get the domain global groups */
-
- status = domain->methods->enum_dom_groups(domain, mem_ctx, &num_entries, &sam_grp_entries);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("get_sam_group_entries: could not enumerate domain groups! Error: %s\n", nt_errstr(status)));
- result = False;
- goto done;
- }
-
- /* Copy entries into return buffer */
-
- if (num_entries) {
- if ( !(name_list = malloc(sizeof(struct acct_info) * num_entries)) ) {
- DEBUG(0,("get_sam_group_entries: Failed to malloc memory for %d domain groups!\n",
- num_entries));
- result = False;
- goto done;
- }
- memcpy( name_list, sam_grp_entries, num_entries * sizeof(struct acct_info) );
- }
-
- ent->num_sam_entries = num_entries;
-
- /* get the domain local groups if we are a member of
- a native win2k domain */
-
- if ( domain->native_mode && domain->methods->enum_local_groups )
- {
- DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n"));
-
- status = domain->methods->enum_local_groups(domain, mem_ctx, &num_entries, &sam_grp_entries);
-
- if ( !NT_STATUS_IS_OK(status) ) {
- DEBUG(3,("get_sam_group_entries: Failed to enumerate domain local groups!\n"));
- num_entries = 0;
- }
- else
- DEBUG(4,("get_sam_group_entries: Returned %d local groups\n", num_entries));
-
- /* Copy entries into return buffer */
-
- if ( num_entries ) {
- if ( !(tmp_name_list = Realloc( name_list, sizeof(struct acct_info) * (ent->num_sam_entries+num_entries))) )
- {
- DEBUG(0,("get_sam_group_entries: Failed to realloc more memory for %d local groups!\n",
- num_entries));
- result = False;
- SAFE_FREE( name_list );
- goto done;
- }
-
- name_list = tmp_name_list;
-
- memcpy( &name_list[ent->num_sam_entries], sam_grp_entries,
- num_entries * sizeof(struct acct_info) );
- }
-
- ent->num_sam_entries += num_entries;
- }
-
-
- /* Fill in remaining fields */
-
- ent->sam_entries = name_list;
- ent->sam_entry_index = 0;
-
- result = (ent->num_sam_entries > 0);
-
- done:
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-/* Fetch next group entry from ntdom database */
-
-#define MAX_GETGRENT_GROUPS 500
-
-enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
-{
- struct getent_state *ent;
- struct winbindd_gr *group_list = NULL;
- int num_groups, group_list_ndx = 0, i, gr_mem_list_len = 0;
- char *new_extra_data, *gr_mem_list = NULL;
-
- DEBUG(3, ("[%5d]: getgrent\n", state->pid));
-
- /* Check user has enabled this */
-
- if (!lp_winbind_enum_groups())
- return WINBINDD_ERROR;
-
- num_groups = MIN(MAX_GETGRENT_GROUPS, state->request.data.num_entries);
-
- if ((state->response.extra_data =
- malloc(num_groups * sizeof(struct winbindd_gr))) == NULL)
- return WINBINDD_ERROR;
-
- state->response.data.num_entries = 0;
-
- group_list = (struct winbindd_gr *)state->response.extra_data;
-
- if (!(ent = state->getgrent_state))
- return WINBINDD_ERROR;
-
- /* Start sending back groups */
-
- for (i = 0; i < num_groups; i++) {
- struct acct_info *name_list = NULL;
- fstring domain_group_name;
- uint32 result;
- gid_t group_gid;
- int gr_mem_len;
- char *gr_mem, *new_gr_mem_list;
- DOM_SID group_sid;
- struct winbindd_domain *domain;
-
- /* Do we need to fetch another chunk of groups? */
-
- tryagain:
-
- DEBUG(10, ("entry_index = %d, num_entries = %d\n",
- ent->sam_entry_index, ent->num_sam_entries));
-
- if (ent->num_sam_entries == ent->sam_entry_index) {
-
- while(ent && !get_sam_group_entries(ent)) {
- struct getent_state *next_ent;
-
- DEBUG(10, ("freeing state info for domain %s\n", ent->domain_name));
-
- /* Free state information for this domain */
-
- SAFE_FREE(ent->sam_entries);
-
- next_ent = ent->next;
- DLIST_REMOVE(state->getgrent_state, ent);
-
- SAFE_FREE(ent);
- ent = next_ent;
- }
-
- /* No more domains */
-
- if (!ent)
- break;
- }
-
- name_list = ent->sam_entries;
-
- if (!(domain =
- find_domain_from_name(ent->domain_name))) {
- DEBUG(3, ("No such domain %s in winbindd_getgrent\n", ent->domain_name));
- result = False;
- goto done;
- }
-
- /* Lookup group info */
-
- sid_copy(&group_sid, &domain->sid);
- sid_append_rid(&group_sid, name_list[ent->sam_entry_index].rid);
-
- if (!winbindd_idmap_get_gid_from_sid(
- &group_sid,
- &group_gid)) {
-
- DEBUG(1, ("could not look up gid for group %s\n",
- name_list[ent->sam_entry_index].acct_name));
-
- ent->sam_entry_index++;
- goto tryagain;
- }
-
- DEBUG(10, ("got gid %d for group %x\n", group_gid,
- name_list[ent->sam_entry_index].rid));
-
- /* Fill in group entry */
-
- fill_domain_username(domain_group_name, ent->domain_name,
- name_list[ent->sam_entry_index].acct_name);
-
- result = fill_grent(&group_list[group_list_ndx],
- ent->domain_name,
- name_list[ent->sam_entry_index].acct_name,
- group_gid);
-
- /* Fill in group membership entry */
-
- if (result) {
- DOM_SID member_sid;
- group_list[group_list_ndx].num_gr_mem = 0;
- gr_mem = NULL;
- gr_mem_len = 0;
-
- /* Get group membership */
- if (state->request.cmd == WINBINDD_GETGRLST) {
- result = True;
- } else {
- sid_copy(&member_sid, &domain->sid);
- sid_append_rid(&member_sid, name_list[ent->sam_entry_index].rid);
- result = fill_grent_mem(
- domain,
- &member_sid,
- SID_NAME_DOM_GRP,
- &group_list[group_list_ndx].num_gr_mem,
- &gr_mem, &gr_mem_len);
- }
- }
-
- if (result) {
- /* Append to group membership list */
- new_gr_mem_list = Realloc(
- gr_mem_list,
- gr_mem_list_len + gr_mem_len);
-
- if (!new_gr_mem_list && (group_list[group_list_ndx].num_gr_mem != 0)) {
- DEBUG(0, ("out of memory\n"));
- SAFE_FREE(gr_mem_list);
- gr_mem_list_len = 0;
- break;
- }
-
- DEBUG(10, ("list_len = %d, mem_len = %d\n",
- gr_mem_list_len, gr_mem_len));
-
- gr_mem_list = new_gr_mem_list;
-
- memcpy(&gr_mem_list[gr_mem_list_len], gr_mem,
- gr_mem_len);
-
- SAFE_FREE(gr_mem);
-
- group_list[group_list_ndx].gr_mem_ofs =
- gr_mem_list_len;
-
- gr_mem_list_len += gr_mem_len;
- }
-
- ent->sam_entry_index++;
-
- /* Add group to return list */
-
- if (result) {
-
- DEBUG(10, ("adding group num_entries = %d\n",
- state->response.data.num_entries));
-
- group_list_ndx++;
- state->response.data.num_entries++;
-
- state->response.length +=
- sizeof(struct winbindd_gr);
-
- } else {
- DEBUG(0, ("could not lookup domain group %s\n",
- domain_group_name));
- }
- }
-
- /* Copy the list of group memberships to the end of the extra data */
-
- if (group_list_ndx == 0)
- goto done;
-
- new_extra_data = Realloc(
- state->response.extra_data,
- group_list_ndx * sizeof(struct winbindd_gr) + gr_mem_list_len);
-
- if (!new_extra_data) {
- DEBUG(0, ("out of memory\n"));
- group_list_ndx = 0;
- SAFE_FREE(state->response.extra_data);
- SAFE_FREE(gr_mem_list);
-
- return WINBINDD_ERROR;
- }
-
- state->response.extra_data = new_extra_data;
-
- memcpy(&((char *)state->response.extra_data)
- [group_list_ndx * sizeof(struct winbindd_gr)],
- gr_mem_list, gr_mem_list_len);
-
- SAFE_FREE(gr_mem_list);
-
- state->response.length += gr_mem_list_len;
-
- DEBUG(10, ("returning %d groups, length = %d\n",
- group_list_ndx, gr_mem_list_len));
-
- /* Out of domains */
-
- done:
-
- return (group_list_ndx > 0) ? WINBINDD_OK : WINBINDD_ERROR;
-}
-
-/* List domain groups without mapping to unix ids */
-
-enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
-{
- uint32 total_entries = 0;
- struct winbindd_domain *domain;
- char *extra_data = NULL;
- char *ted = NULL;
- unsigned int extra_data_len = 0, i;
-
- DEBUG(3, ("[%5d]: list groups\n", state->pid));
-
- /* Enumerate over trusted domains */
-
- for (domain = domain_list(); domain; domain = domain->next) {
- struct getent_state groups;
-
- ZERO_STRUCT(groups);
-
- /* Get list of sam groups */
- ZERO_STRUCT(groups);
- fstrcpy(groups.domain_name, domain->name);
-
- get_sam_group_entries(&groups);
-
- if (groups.num_sam_entries == 0) {
- /* this domain is empty or in an error state */
- continue;
- }
-
- /* keep track the of the total number of groups seen so
- far over all domains */
- total_entries += groups.num_sam_entries;
-
- /* Allocate some memory for extra data. Note that we limit
- account names to sizeof(fstring) = 128 characters. */
- ted = Realloc(extra_data, sizeof(fstring) * total_entries);
-
- if (!ted) {
- DEBUG(0,("failed to enlarge buffer!\n"));
- SAFE_FREE(extra_data);
- return WINBINDD_ERROR;
- } else
- extra_data = ted;
-
- /* Pack group list into extra data fields */
- for (i = 0; i < groups.num_sam_entries; i++) {
- char *group_name = ((struct acct_info *)
- groups.sam_entries)[i].acct_name;
- fstring name;
-
- fill_domain_username(name, domain->name, group_name);
- /* Append to extra data */
- memcpy(&extra_data[extra_data_len], name,
- strlen(name));
- extra_data_len += strlen(name);
- extra_data[extra_data_len++] = ',';
- }
-
- free(groups.sam_entries);
- }
-
- /* Assign extra_data fields in response structure */
- if (extra_data) {
- extra_data[extra_data_len - 1] = '\0';
- state->response.extra_data = extra_data;
- state->response.length += extra_data_len;
- }
-
- /* No domains may have responded but that's still OK so don't
- return an error. */
-
- return WINBINDD_OK;
-}
-
-/* Get user supplementary groups. This is much quicker than trying to
- invert the groups database. */
-
-enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
-{
- fstring name_domain, name_user;
- DOM_SID user_sid;
- enum SID_NAME_USE name_type;
- uint32 num_groups, num_gids;
- NTSTATUS status;
- DOM_SID **user_gids;
- struct winbindd_domain *domain;
- enum winbindd_result result = WINBINDD_ERROR;
- gid_t *gid_list;
- unsigned int i;
- TALLOC_CTX *mem_ctx;
-
- /* Ensure null termination */
- state->request.data.username[sizeof(state->request.data.username)-1]='\0';
-
- DEBUG(3, ("[%5d]: getgroups %s\n", state->pid,
- state->request.data.username));
-
- if (!(mem_ctx = talloc_init("winbindd_getgroups(%s)",
- state->request.data.username)))
- return WINBINDD_ERROR;
-
- /* Parse domain and username */
-
- if (!parse_domain_user(state->request.data.username, name_domain,
- name_user))
- goto done;
-
- /* Get info for the domain */
-
- if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(0, ("could not find domain entry for domain %s\n",
- name_domain));
- goto done;
- }
-
- /* Get rid and name type from name. The following costs 1 packet */
-
- if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid,
- &name_type)) {
- DEBUG(1, ("user '%s' does not exist\n", name_user));
- goto done;
- }
-
- if (name_type != SID_NAME_USER) {
- DEBUG(1, ("name '%s' is not a user name: %d\n",
- name_user, name_type));
- goto done;
- }
-
- status = domain->methods->lookup_usergroups(domain, mem_ctx,
- &user_sid, &num_groups,
- &user_gids);
- if (!NT_STATUS_IS_OK(status)) goto done;
-
- /* Copy data back to client */
-
- num_gids = 0;
- gid_list = malloc(sizeof(gid_t) * num_groups);
-
- if (state->response.extra_data)
- goto done;
-
- for (i = 0; i < num_groups; i++) {
- if (!winbindd_idmap_get_gid_from_sid(
- user_gids[i],
- &gid_list[num_gids])) {
- fstring sid_string;
-
- DEBUG(1, ("unable to convert group sid %s to gid\n",
- sid_to_string(sid_string, user_gids[i])));
- continue;
- }
-
- num_gids++;
- }
-
- state->response.data.num_entries = num_gids;
- state->response.extra_data = gid_list;
- state->response.length += num_gids * sizeof(gid_t);
-
- result = WINBINDD_OK;
-
- done:
-
- talloc_destroy(mem_ctx);
-
- return result;
-}
diff --git a/source4/nsswitch/winbindd_idmap.c b/source4/nsswitch/winbindd_idmap.c
deleted file mode 100644
index de547cde41..0000000000
--- a/source4/nsswitch/winbindd_idmap.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Winbind ID Mapping
- Copyright (C) Tim Potter 2000
- Copyright (C) Anthony Liguori <aliguor@us.ibm.com> 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 "winbindd.h"
-
-static struct {
- const char *name;
- /* Function to create a member of the idmap_methods list */
- BOOL (*reg_meth)(struct idmap_methods **methods);
- struct idmap_methods *methods;
-} builtin_idmap_functions[] = {
- { "tdb", winbind_idmap_reg_tdb, NULL },
- /* { "ldap", winbind_idmap_reg_ldap, NULL },*/
- { NULL, NULL, NULL }
-};
-
-/* singleton pattern: uberlazy evaluation */
-static struct idmap_methods *impl;
-
-static struct idmap_methods *get_impl(const char *name)
-{
- int i = 0;
- struct idmap_methods *ret = NULL;
-
- while (builtin_idmap_functions[i].name &&
- strcmp(builtin_idmap_functions[i].name, name)) {
- i++;
- }
-
- if (builtin_idmap_functions[i].name) {
- if (!builtin_idmap_functions[i].methods) {
- builtin_idmap_functions[i].reg_meth(&builtin_idmap_functions[i].methods);
- }
-
- ret = builtin_idmap_functions[i].methods;
- }
-
- return ret;
-}
-
-/* Initialize backend */
-BOOL winbindd_idmap_init(void)
-{
- BOOL ret = False;
-
- DEBUG(3, ("winbindd_idmap_init: using '%s' as backend\n",
- lp_idmap_backend()));
-
- if (!impl) {
- impl = get_impl(lp_idmap_backend());
- if (!impl) {
- DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
- lp_idmap_backend()));
- }
- }
-
- if (impl) {
- ret = impl->init();
- }
-
- DEBUG(3, ("winbind_idmap_init: returning %s\n", ret ? "true" : "false"));
-
- return ret;
-}
-
-/* Get UID from SID */
-BOOL winbindd_idmap_get_uid_from_sid(DOM_SID *sid, uid_t *uid)
-{
- BOOL ret = False;
-
- if (!impl) {
- impl = get_impl(lp_idmap_backend());
- if (!impl) {
- DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
- lp_idmap_backend()));
- }
- }
-
- if (impl) {
- ret = impl->get_uid_from_sid(sid, uid);
- }
-
- return ret;
-}
-
-/* Get GID from SID */
-BOOL winbindd_idmap_get_gid_from_sid(DOM_SID *sid, gid_t *gid)
-{
- BOOL ret = False;
-
- if (!impl) {
- impl = get_impl(lp_idmap_backend());
- if (!impl) {
- DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
- lp_idmap_backend()));
- }
- }
-
- if (impl) {
- ret = impl->get_gid_from_sid(sid, gid);
- }
-
- return ret;
-}
-
-/* Get SID from UID */
-BOOL winbindd_idmap_get_sid_from_uid(uid_t uid, DOM_SID *sid)
-{
- BOOL ret = False;
-
- if (!impl) {
- impl = get_impl(lp_idmap_backend());
- if (!impl) {
- DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
- lp_idmap_backend()));
- }
- }
-
- if (impl) {
- ret = impl->get_sid_from_uid(uid, sid);
- }
-
- return ret;
-}
-
-/* Get SID from GID */
-BOOL winbindd_idmap_get_sid_from_gid(gid_t gid, DOM_SID *sid)
-{
- BOOL ret = False;
-
- if (!impl) {
- impl = get_impl(lp_idmap_backend());
- }
-
- if (impl) {
- ret = impl->get_sid_from_gid(gid, sid);
- } else {
- DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
- lp_idmap_backend()));
- }
-
- return ret;
-}
-
-/* Close backend */
-BOOL winbindd_idmap_close(void)
-{
- BOOL ret = False;
-
- if (!impl) {
- impl = get_impl(lp_idmap_backend());
- }
-
- if (impl) {
- ret = impl->close();
- } else {
- DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
- lp_idmap_backend()));
- }
-
- return ret;
-}
-
-/* Dump backend status */
-void winbindd_idmap_status(void)
-{
- if (!impl) {
- impl = get_impl(lp_idmap_backend());
- }
-
- if (impl) {
- impl->status();
- } else {
- DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
- lp_idmap_backend()));
- }
-}
-
diff --git a/source4/nsswitch/winbindd_idmap_tdb.c b/source4/nsswitch/winbindd_idmap_tdb.c
deleted file mode 100644
index 911b3b41d2..0000000000
--- a/source4/nsswitch/winbindd_idmap_tdb.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon - user related function
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Anthony Liguori 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 "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/* High water mark keys */
-#define HWM_GROUP "GROUP HWM"
-#define HWM_USER "USER HWM"
-
-/* idmap version determines auto-conversion */
-#define IDMAP_VERSION 2
-
-/* Globals */
-static TDB_CONTEXT *idmap_tdb;
-
-/* convert one record to the new format */
-static int tdb_convert_fn(TDB_CONTEXT * tdb, TDB_DATA key, TDB_DATA data,
- void *ignored)
-{
- struct winbindd_domain *domain;
- char *p;
- DOM_SID sid;
- uint32 rid;
- fstring keystr;
- fstring dom_name;
- TDB_DATA key2;
-
- p = strchr(key.dptr, '/');
- if (!p)
- return 0;
-
- *p = 0;
- fstrcpy(dom_name, key.dptr);
- *p++ = '/';
-
- domain = find_domain_from_name(dom_name);
- if (!domain) {
- /* We must delete the old record. */
- DEBUG(0,
- ("winbindd: tdb_convert_fn : Unable to find domain %s\n",
- dom_name));
- DEBUG(0,
- ("winbindd: tdb_convert_fn : deleting record %s\n",
- key.dptr));
- tdb_delete(idmap_tdb, key);
- return 0;
- }
-
- rid = atoi(p);
-
- sid_copy(&sid, &domain->sid);
- sid_append_rid(&sid, rid);
-
- sid_to_string(keystr, &sid);
- key2.dptr = keystr;
- key2.dsize = strlen(keystr) + 1;
-
- if (tdb_store(idmap_tdb, key2, data, TDB_INSERT) != 0) {
- /* not good! */
- DEBUG(0,
- ("winbindd: tdb_convert_fn : Unable to update record %s\n",
- key2.dptr));
- DEBUG(0,
- ("winbindd: tdb_convert_fn : conversion failed - idmap corrupt ?\n"));
- return -1;
- }
-
- if (tdb_store(idmap_tdb, data, key2, TDB_REPLACE) != 0) {
- /* not good! */
- DEBUG(0,
- ("winbindd: tdb_convert_fn : Unable to update record %s\n",
- data.dptr));
- DEBUG(0,
- ("winbindd: tdb_convert_fn : conversion failed - idmap corrupt ?\n"));
- return -1;
- }
-
- tdb_delete(idmap_tdb, key);
-
- return 0;
-}
-
-/*****************************************************************************
- Convert the idmap database from an older version.
-*****************************************************************************/
-static BOOL tdb_idmap_convert(const char *idmap_name)
-{
- int32 vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");
- BOOL bigendianheader =
- (idmap_tdb->flags & TDB_BIGENDIAN) ? True : False;
-
- if (vers == IDMAP_VERSION)
- return True;
-
- if (((vers == -1) && bigendianheader)
- || (IREV(vers) == IDMAP_VERSION)) {
- /* Arrggghh ! Bytereversed or old big-endian - make order independent ! */
- /*
- * high and low records were created on a
- * big endian machine and will need byte-reversing.
- */
-
- int32 wm;
-
- wm = tdb_fetch_int32(idmap_tdb, HWM_USER);
-
- if (wm != -1) {
- wm = IREV(wm);
- } else
- wm = server_state.uid_low;
-
- if (tdb_store_int32(idmap_tdb, HWM_USER, wm) == -1) {
- DEBUG(0,
- ("tdb_idmap_convert: Unable to byteswap user hwm in idmap database\n"));
- return False;
- }
-
- wm = tdb_fetch_int32(idmap_tdb, HWM_GROUP);
- if (wm != -1) {
- wm = IREV(wm);
- } else
- wm = server_state.gid_low;
-
- if (tdb_store_int32(idmap_tdb, HWM_GROUP, wm) == -1) {
- DEBUG(0,
- ("tdb_idmap_convert: Unable to byteswap group hwm in idmap database\n"));
- return False;
- }
- }
-
- /* the old format stored as DOMAIN/rid - now we store the SID direct */
- tdb_traverse(idmap_tdb, tdb_convert_fn, NULL);
-
- if (tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION) ==
- -1) {
- DEBUG(0,
- ("tdb_idmap_convert: Unable to byteswap group hwm in idmap database\n"));
- return False;
- }
-
- return True;
-}
-
-/* Allocate either a user or group id from the pool */
-static BOOL tdb_allocate_id(uid_t * id, BOOL isgroup)
-{
- int hwm;
-
- /* Get current high water mark */
- if ((hwm = tdb_fetch_int32(idmap_tdb,
- isgroup ? HWM_GROUP : HWM_USER)) ==
- -1) {
- return False;
- }
-
- /* Return next available uid in list */
- if ((isgroup && (hwm > server_state.gid_high)) ||
- (!isgroup && (hwm > server_state.uid_high))) {
- DEBUG(0,
- ("winbind %sid range full!\n", isgroup ? "g" : "u"));
- return False;
- }
-
- if (id) {
- *id = hwm;
- }
-
- hwm++;
-
- /* Store new high water mark */
- tdb_store_int32(idmap_tdb, isgroup ? HWM_GROUP : HWM_USER, hwm);
-
- return True;
-}
-
-/* Get a sid from an id */
-static BOOL tdb_get_sid_from_id(int id, DOM_SID * sid, BOOL isgroup)
-{
- TDB_DATA key, data;
- fstring keystr;
- BOOL result = False;
-
- slprintf(keystr, sizeof(keystr), "%s %d", isgroup ? "GID" : "UID",
- id);
-
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- data = tdb_fetch(idmap_tdb, key);
-
- if (data.dptr) {
- result = string_to_sid(sid, data.dptr);
- SAFE_FREE(data.dptr);
- }
-
- return result;
-}
-
-/* Get an id from a sid */
-static BOOL tdb_get_id_from_sid(DOM_SID * sid, uid_t * id, BOOL isgroup)
-{
- TDB_DATA data, key;
- fstring keystr;
- BOOL result = False;
-
- /* Check if sid is present in database */
- sid_to_string(keystr, sid);
-
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- data = tdb_fetch(idmap_tdb, key);
-
- if (data.dptr) {
- fstring scanstr;
- int the_id;
-
- /* Parse and return existing uid */
- fstrcpy(scanstr, isgroup ? "GID" : "UID");
- fstrcat(scanstr, " %d");
-
- if (sscanf(data.dptr, scanstr, &the_id) == 1) {
- /* Store uid */
- if (id) {
- *id = the_id;
- }
-
- result = True;
- }
-
- SAFE_FREE(data.dptr);
- } else {
-
- /* Allocate a new id for this sid */
- if (id && tdb_allocate_id(id, isgroup)) {
- fstring keystr2;
-
- /* Store new id */
- slprintf(keystr2, sizeof(keystr2), "%s %d",
- isgroup ? "GID" : "UID", *id);
-
- data.dptr = keystr2;
- data.dsize = strlen(keystr2) + 1;
-
- tdb_store(idmap_tdb, key, data, TDB_REPLACE);
- tdb_store(idmap_tdb, data, key, TDB_REPLACE);
-
- result = True;
- }
- }
-
- return result;
-}
-
-/*****************************************************************************
- Initialise idmap database.
-*****************************************************************************/
-static BOOL tdb_idmap_init(void)
-{
- /* Open tdb cache */
- if (!(idmap_tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
- TDB_DEFAULT, O_RDWR | O_CREAT,
- 0600))) {
- DEBUG(0,
- ("winbindd_idmap_init: Unable to open idmap database\n"));
- return False;
- }
-
- /* possibly convert from an earlier version */
- if (!tdb_idmap_convert(lock_path("winbindd_idmap.tdb"))) {
- DEBUG(0,
- ("winbindd_idmap_init: Unable to open idmap database\n"));
- return False;
- }
-
- /* Create high water marks for group and user id */
- if (tdb_fetch_int32(idmap_tdb, HWM_USER) == -1) {
- if (tdb_store_int32
- (idmap_tdb, HWM_USER, server_state.uid_low) == -1) {
- DEBUG(0,
- ("winbindd_idmap_init: Unable to initialise user hwm in idmap database\n"));
- return False;
- }
- }
-
- if (tdb_fetch_int32(idmap_tdb, HWM_GROUP) == -1) {
- if (tdb_store_int32
- (idmap_tdb, HWM_GROUP, server_state.gid_low) == -1) {
- DEBUG(0,
- ("winbindd_idmap_init: Unable to initialise group hwm in idmap database\n"));
- return False;
- }
- }
-
- return True;
-}
-
-/* Get a sid from a uid */
-static BOOL tdb_get_sid_from_uid(uid_t uid, DOM_SID * sid)
-{
- return tdb_get_sid_from_id((int) uid, sid, False);
-}
-
-/* Get a sid from a gid */
-static BOOL tdb_get_sid_from_gid(gid_t gid, DOM_SID * sid)
-{
- return tdb_get_sid_from_id((int) gid, sid, True);
-}
-
-/* Get a uid from a sid */
-static BOOL tdb_get_uid_from_sid(DOM_SID * sid, uid_t * uid)
-{
- return tdb_get_id_from_sid(sid, uid, False);
-}
-
-/* Get a gid from a group sid */
-static BOOL tdb_get_gid_from_sid(DOM_SID * sid, gid_t * gid)
-{
- return tdb_get_id_from_sid(sid, gid, True);
-}
-
-/* Close the tdb */
-static BOOL tdb_idmap_close(void)
-{
- if (idmap_tdb)
- return (tdb_close(idmap_tdb) == 0);
- return True;
-}
-
-
-/* Dump status information to log file. Display different stuff based on
- the debug level:
-
- Debug Level Information Displayed
- =================================================================
- 0 Percentage of [ug]id range allocated
- 0 High water marks (next allocated ids)
-*/
-
-#define DUMP_INFO 0
-
-static void tdb_idmap_status(void)
-{
- int user_hwm, group_hwm;
-
- DEBUG(0, ("winbindd idmap status:\n"));
-
- /* Get current high water marks */
-
- if ((user_hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) {
- DEBUG(DUMP_INFO,
- ("\tCould not get userid high water mark!\n"));
- }
-
- if ((group_hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) {
- DEBUG(DUMP_INFO,
- ("\tCould not get groupid high water mark!\n"));
- }
-
- /* Display next ids to allocate */
-
- if (user_hwm != -1) {
- DEBUG(DUMP_INFO,
- ("\tNext userid to allocate is %d\n", user_hwm));
- }
-
- if (group_hwm != -1) {
- DEBUG(DUMP_INFO,
- ("\tNext groupid to allocate is %d\n", group_hwm));
- }
-
- /* Display percentage of id range already allocated. */
-
- if (user_hwm != -1) {
- int num_users = user_hwm - server_state.uid_low;
- int total_users =
- server_state.uid_high - server_state.uid_low;
-
- DEBUG(DUMP_INFO,
- ("\tUser id range is %d%% full (%d of %d)\n",
- num_users * 100 / total_users, num_users,
- total_users));
- }
-
- if (group_hwm != -1) {
- int num_groups = group_hwm - server_state.gid_low;
- int total_groups =
- server_state.gid_high - server_state.gid_low;
-
- DEBUG(DUMP_INFO,
- ("\tGroup id range is %d%% full (%d of %d)\n",
- num_groups * 100 / total_groups, num_groups,
- total_groups));
- }
-
- /* Display complete mapping of users and groups to rids */
-}
-
-struct idmap_methods tdb_idmap_methods = {
- tdb_idmap_init,
-
- tdb_get_sid_from_uid,
- tdb_get_sid_from_gid,
-
- tdb_get_uid_from_sid,
- tdb_get_gid_from_sid,
-
- tdb_idmap_close,
-
- tdb_idmap_status
-};
-
-BOOL winbind_idmap_reg_tdb(struct idmap_methods **meth)
-{
- *meth = &tdb_idmap_methods;
-
- return True;
-}
diff --git a/source4/nsswitch/winbindd_misc.c b/source4/nsswitch/winbindd_misc.c
deleted file mode 100644
index b85cd0570d..0000000000
--- a/source4/nsswitch/winbindd_misc.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon - miscellaneous other functions
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Andrew Bartlett 2002
-
- 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 "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/* Check the machine account password is valid */
-
-enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *state)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uchar trust_passwd[16];
- int num_retries = 0;
- struct cli_state *cli;
- DEBUG(3, ("[%5d]: check machine account\n", state->pid));
-
- /* Get trust account password */
-
- again:
- if (!secrets_fetch_trust_account_password(
- lp_workgroup(), trust_passwd, NULL)) {
- result = NT_STATUS_INTERNAL_ERROR;
- goto done;
- }
-
- /* This call does a cli_nt_setup_creds() which implicitly checks
- the trust account password. */
-
- /* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
- goto done;
- }
-
- /* There is a race condition between fetching the trust account
- password and the periodic machine password change. So it's
- possible that the trust account password has been changed on us.
- We are returned NT_STATUS_ACCESS_DENIED if this happens. */
-
-#define MAX_RETRIES 8
-
- if ((num_retries < MAX_RETRIES) &&
- NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
- num_retries++;
- goto again;
- }
-
- /* Pass back result code - zero for success, other values for
- specific failures. */
-
- DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(result) ?
- "good" : "bad"));
-
- done:
- state->response.data.auth.nt_status = NT_STATUS_V(result);
- fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
- fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
- state->response.data.auth.pam_error = nt_status_to_pam(result);
-
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Checking the trust account password returned %s\n",
- state->response.data.auth.nt_status_string));
-
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
-}
-
-enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
- *state)
-{
- struct winbindd_domain *domain;
- int total_entries = 0, extra_data_len = 0;
- char *ted, *extra_data = NULL;
-
- DEBUG(3, ("[%5d]: list trusted domains\n", state->pid));
-
- /* We need to refresh the trusted domain list as the domains may
- have changed since we last looked. There may be a sequence
- number or something we should use but I haven't found it yet. */
-
- if (!init_domain_list()) {
- DEBUG(1, ("winbindd_list_trusted_domains: could not "
- "refresh trusted domain list\n"));
- return WINBINDD_ERROR;
- }
-
- for(domain = domain_list(); domain; domain = domain->next) {
-
- /* Skip own domain */
-
- if (strequal(domain->name, lp_workgroup())) continue;
-
- /* Add domain to list */
-
- total_entries++;
- ted = Realloc(extra_data, sizeof(fstring) *
- total_entries);
-
- if (!ted) {
- DEBUG(0,("winbindd_list_trusted_domains: failed to enlarge buffer!\n"));
- SAFE_FREE(extra_data);
- return WINBINDD_ERROR;
- } else
- extra_data = ted;
-
- memcpy(&extra_data[extra_data_len], domain->name,
- strlen(domain->name));
-
- extra_data_len += strlen(domain->name);
- extra_data[extra_data_len++] = ',';
- }
-
- if (extra_data) {
- if (extra_data_len > 1)
- extra_data[extra_data_len - 1] = '\0';
- state->response.extra_data = extra_data;
- state->response.length += extra_data_len;
- }
-
- return WINBINDD_OK;
-}
-
-
-enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state)
-{
- struct winbindd_domain *domain;
- char *extra_data = NULL;
-
- DEBUG(3, ("[%5d]: show sequence\n", state->pid));
-
- extra_data = strdup("");
-
- /* this makes for a very simple data format, and is easily parsable as well
- if that is ever needed */
- for (domain = domain_list(); domain; domain = domain->next) {
- char *s;
-
- domain->methods->sequence_number(domain, &domain->sequence_number);
-
- if (DOM_SEQUENCE_NONE == (unsigned)domain->sequence_number) {
- asprintf(&s,"%s%s : DISCONNECTED\n", extra_data,
- domain->name);
- } else {
- asprintf(&s,"%s%s : %u\n", extra_data,
- domain->name, (unsigned)domain->sequence_number);
- }
- free(extra_data);
- extra_data = s;
- }
-
- state->response.extra_data = extra_data;
- /* must add one to length to copy the 0 for string termination */
- state->response.length += strlen(extra_data) + 1;
-
- return WINBINDD_OK;
-}
-
-enum winbindd_result winbindd_ping(struct winbindd_cli_state
- *state)
-{
- DEBUG(3, ("[%5d]: ping\n", state->pid));
-
- return WINBINDD_OK;
-}
-
-/* List various tidbits of information */
-
-enum winbindd_result winbindd_info(struct winbindd_cli_state *state)
-{
-
- DEBUG(3, ("[%5d]: request misc info\n", state->pid));
-
- state->response.data.info.winbind_separator = *lp_winbind_separator();
- fstrcpy(state->response.data.info.samba_version, VERSION);
-
- return WINBINDD_OK;
-}
-
-/* Tell the client the current interface version */
-
-enum winbindd_result winbindd_interface_version(struct winbindd_cli_state *state)
-{
-
- DEBUG(3, ("[%5d]: request interface version\n", state->pid));
-
- state->response.data.interface_version = WINBIND_INTERFACE_VERSION;
-
- return WINBINDD_OK;
-}
-
-/* What domain are we a member of? */
-
-enum winbindd_result winbindd_domain_name(struct winbindd_cli_state *state)
-{
-
- DEBUG(3, ("[%5d]: request domain name\n", state->pid));
-
- fstrcpy(state->response.data.domain_name, lp_workgroup());
-
- return WINBINDD_OK;
-}
-
-/* What's my name again? */
-
-enum winbindd_result winbindd_netbios_name(struct winbindd_cli_state *state)
-{
-
- DEBUG(3, ("[%5d]: request netbios name\n", state->pid));
-
- fstrcpy(state->response.data.netbios_name, lp_netbios_name());
-
- return WINBINDD_OK;
-}
diff --git a/source4/nsswitch/winbindd_nss.h b/source4/nsswitch/winbindd_nss.h
deleted file mode 100644
index 2c87a77100..0000000000
--- a/source4/nsswitch/winbindd_nss.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#ifndef SAFE_FREE
-#define SAFE_FREE(x) do { if(x) {free(x); x=NULL;} } while(0)
-#endif
-
-#ifndef _WINBINDD_NTDOM_H
-#define _WINBINDD_NTDOM_H
-
-#define WINBINDD_SOCKET_NAME "pipe" /* Name of PF_UNIX socket */
-#define WINBINDD_SOCKET_DIR "/tmp/.winbindd" /* Name of PF_UNIX dir */
-
-#define WINBINDD_DOMAIN_ENV "WINBINDD_DOMAIN" /* Environment variables */
-#define WINBINDD_DONT_ENV "_NO_WINBINDD"
-
-/* Update this when you change the interface. */
-
-#define WINBIND_INTERFACE_VERSION 7
-
-/* Socket commands */
-
-enum winbindd_cmd {
-
- WINBINDD_INTERFACE_VERSION, /* Always a well known value */
-
- /* Get users and groups */
-
- WINBINDD_GETPWNAM,
- WINBINDD_GETPWUID,
- WINBINDD_GETGRNAM,
- WINBINDD_GETGRGID,
- WINBINDD_GETGROUPS,
-
- /* Enumerate users and groups */
-
- WINBINDD_SETPWENT,
- WINBINDD_ENDPWENT,
- WINBINDD_GETPWENT,
- WINBINDD_SETGRENT,
- WINBINDD_ENDGRENT,
- WINBINDD_GETGRENT,
-
- /* PAM authenticate and password change */
-
- WINBINDD_PAM_AUTH,
- WINBINDD_PAM_AUTH_CRAP,
- WINBINDD_PAM_CHAUTHTOK,
-
- /* List various things */
-
- WINBINDD_LIST_USERS, /* List w/o rid->id mapping */
- WINBINDD_LIST_GROUPS, /* Ditto */
- WINBINDD_LIST_TRUSTDOM,
-
- /* SID conversion */
-
- WINBINDD_LOOKUPSID,
- WINBINDD_LOOKUPNAME,
-
- /* Lookup functions */
-
- WINBINDD_SID_TO_UID,
- WINBINDD_SID_TO_GID,
- WINBINDD_UID_TO_SID,
- WINBINDD_GID_TO_SID,
-
- /* Miscellaneous other stuff */
-
- WINBINDD_CHECK_MACHACC, /* Check machine account pw works */
- WINBINDD_PING, /* Just tell me winbind is running */
- WINBINDD_INFO, /* Various bit of info. Currently just tidbits */
- WINBINDD_DOMAIN_NAME, /* The domain this winbind server is a member of (lp_workgroup()) */
-
- WINBINDD_SHOW_SEQUENCE, /* display sequence numbers of domains */
-
- /* WINS commands */
-
- WINBINDD_WINS_BYIP,
- WINBINDD_WINS_BYNAME,
-
- /* this is like GETGRENT but gives an empty group list */
- WINBINDD_GETGRLST,
-
- WINBINDD_NETBIOS_NAME, /* The netbios name of the server */
- /* Placeholder for end of cmd list */
-
- WINBINDD_NUM_CMDS
-};
-
-#define WINBIND_PAM_INFO3_NDR 0x0001
-#define WINBIND_PAM_INFO3_TEXT 0x0002
-#define WINBIND_PAM_NTKEY 0x0004
-#define WINBIND_PAM_LMKEY 0x0008
-#define WINBIND_PAM_CONTACT_TRUSTDOM 0x0010
-
-/* Winbind request structure */
-
-struct winbindd_request {
- uint32 length;
- enum winbindd_cmd cmd; /* Winbindd command to execute */
- pid_t pid; /* pid of calling process */
-
- union {
- fstring winsreq; /* WINS request */
- fstring username; /* getpwnam */
- fstring groupname; /* getgrnam */
- uid_t uid; /* getpwuid, uid_to_sid */
- gid_t gid; /* getgrgid, gid_to_sid */
- struct {
- /* We deliberatedly don't split into domain/user to
- avoid having the client know what the separator
- character is. */
- fstring user;
- fstring pass;
- } auth; /* pam_winbind auth module */
- struct {
- unsigned char chal[8];
- fstring user;
- fstring domain;
- fstring lm_resp;
- uint16 lm_resp_len;
- fstring nt_resp;
- uint16 nt_resp_len;
- fstring workstation;
- uint32 flags;
- } auth_crap;
- struct {
- fstring user;
- fstring oldpass;
- fstring newpass;
- } chauthtok; /* pam_winbind passwd module */
- fstring sid; /* lookupsid, sid_to_[ug]id */
- struct {
- fstring dom_name; /* lookupname */
- fstring name;
- } name;
- uint32 num_entries; /* getpwent, getgrent */
- } data;
- char null_term;
-};
-
-/* Response values */
-
-enum winbindd_result {
- WINBINDD_ERROR,
- WINBINDD_OK
-};
-
-/* Winbind response structure */
-
-struct winbindd_response {
-
- /* Header information */
-
- uint32 length; /* Length of response */
- enum winbindd_result result; /* Result code */
-
- /* Fixed length return data */
-
- union {
- int interface_version; /* Try to ensure this is always in the same spot... */
-
- fstring winsresp; /* WINS response */
-
- /* getpwnam, getpwuid */
-
- struct winbindd_pw {
- fstring pw_name;
- fstring pw_passwd;
- uid_t pw_uid;
- gid_t pw_gid;
- fstring pw_gecos;
- fstring pw_dir;
- fstring pw_shell;
- } pw;
-
- /* getgrnam, getgrgid */
-
- struct winbindd_gr {
- fstring gr_name;
- fstring gr_passwd;
- gid_t gr_gid;
- int num_gr_mem;
- int gr_mem_ofs; /* offset to group membership */
- } gr;
-
- uint32 num_entries; /* getpwent, getgrent */
- struct winbindd_sid {
- fstring sid; /* lookupname, [ug]id_to_sid */
- int type;
- } sid;
- struct winbindd_name {
- fstring dom_name; /* lookupsid */
- fstring name;
- int type;
- } name;
- uid_t uid; /* sid_to_uid */
- gid_t gid; /* sid_to_gid */
- struct winbindd_info {
- char winbind_separator;
- fstring samba_version;
- } info;
- fstring domain_name;
- fstring netbios_name;
-
- struct auth_reply {
- uint32 nt_status;
- fstring nt_status_string;
- fstring error_string;
- int pam_error;
- char nt_session_key[16];
- char first_8_lm_hash[8];
- } auth;
- } data;
-
- /* Variable length return data */
-
- void *extra_data; /* getgrnam, getgrgid, getgrent */
-};
-
-#endif
diff --git a/source4/nsswitch/winbindd_pam.c b/source4/nsswitch/winbindd_pam.c
deleted file mode 100644
index 8a0326b42c..0000000000
--- a/source4/nsswitch/winbindd_pam.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon - pam auth funcions
-
- Copyright (C) Andrew Tridgell 2000
- Copyright (C) Tim Potter 2001
- Copyright (C) Andrew Bartlett 2001-2002
-
- 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 "winbindd.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-
-static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
- struct winbindd_cli_state *state,
- NET_USER_INFO_3 *info3)
-{
- prs_struct ps;
- uint32 size;
- if (!prs_init(&ps, 256 /* Random, non-zero number */, mem_ctx, MARSHALL)) {
- return NT_STATUS_NO_MEMORY;
- }
- if (!net_io_user_info3("", info3, &ps, 1, 3)) {
- prs_mem_free(&ps);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- size = prs_data_size(&ps);
- state->response.extra_data = malloc(size);
- if (!state->response.extra_data) {
- prs_mem_free(&ps);
- return NT_STATUS_NO_MEMORY;
- }
- prs_copy_all_data_out(state->response.extra_data, &ps);
- state->response.length += size;
- prs_mem_free(&ps);
- return NT_STATUS_OK;
-}
-
-/* Return a password structure from a username. */
-
-enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
-{
- NTSTATUS result;
- fstring name_domain, name_user;
- unsigned char trust_passwd[16];
- time_t last_change_time;
- uint32 smb_uid_low;
- NET_USER_INFO_3 info3;
- struct cli_state *cli = NULL;
- uchar chal[8];
- TALLOC_CTX *mem_ctx = NULL;
- DATA_BLOB lm_resp;
- DATA_BLOB nt_resp;
-
- /* Ensure null termination */
- state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
-
- /* Ensure null termination */
- state->request.data.auth.pass[sizeof(state->request.data.auth.pass)-1]='\0';
-
- DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
- state->request.data.auth.user));
-
- if (!(mem_ctx = talloc_init("winbind pam auth for %s", state->request.data.auth.user))) {
- DEBUG(0, ("winbindd_pam_auth: could not talloc_init()!\n"));
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- /* Parse domain and username */
-
- if (!parse_domain_user(state->request.data.auth.user, name_domain,
- name_user)) {
- DEBUG(5,("no domain separator (%s) in username (%s) - failing auth\n", lp_winbind_separator(), state->request.data.auth.user));
- result = NT_STATUS_INVALID_PARAMETER;
- goto done;
- }
-
- {
- unsigned char local_lm_response[24];
- unsigned char local_nt_response[24];
-
- generate_random_buffer(chal, 8, False);
- SMBencrypt(state->request.data.auth.pass, chal, local_lm_response);
-
- SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response);
-
- lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response));
- nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response));
- }
-
- /*
- * Get the machine account password for our primary domain
- */
-
- if (!secrets_fetch_trust_account_password(
- lp_workgroup(), trust_passwd, &last_change_time)) {
- DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
- "password for domain %s\n", lp_workgroup()));
- result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- goto done;
- }
-
- /* We really don't care what LUID we give the user. */
-
- generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
-
- ZERO_STRUCT(info3);
-
- /* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
- goto done;
- }
-
- result = cli_netlogon_sam_network_logon(cli, mem_ctx,
- name_user, name_domain,
- lp_netbios_name(), chal,
- lm_resp, nt_resp,
- &info3);
-
- uni_group_cache_store_netlogon(mem_ctx, &info3);
-done:
-
- state->response.data.auth.nt_status = NT_STATUS_V(result);
- fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
- fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
- state->response.data.auth.pam_error = nt_status_to_pam(result);
-
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n",
- state->request.data.auth.user,
- state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
-}
-
-/* Challenge Response Authentication Protocol */
-
-enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
-{
- NTSTATUS result;
- unsigned char trust_passwd[16];
- time_t last_change_time;
- NET_USER_INFO_3 info3;
- struct cli_state *cli = NULL;
- TALLOC_CTX *mem_ctx = NULL;
- char *user = NULL;
- const char *domain = NULL;
- const char *contact_domain;
- const char *workstation;
-
- DATA_BLOB lm_resp, nt_resp;
-
- /* Ensure null termination */
- state->request.data.auth_crap.user[sizeof(state->request.data.auth_crap.user)-1]='\0';
-
- /* Ensure null termination */
- state->request.data.auth_crap.domain[sizeof(state->request.data.auth_crap.domain)-1]='\0';
-
- if (!(mem_ctx = talloc_init("winbind pam auth crap for (utf8) %s", state->request.data.auth_crap.user))) {
- DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n"));
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- if (pull_utf8_talloc(mem_ctx, &user, state->request.data.auth_crap.user) == (size_t)-1) {
- DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
- }
-
- if (*state->request.data.auth_crap.domain) {
- char *dom = NULL;
- if (pull_utf8_talloc(mem_ctx, &dom, state->request.data.auth_crap.domain) == (size_t)-1) {
- DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
- }
- domain = dom;
- } else if (lp_winbind_use_default_domain()) {
- domain = lp_workgroup();
- } else {
- DEBUG(5,("no domain specified with username (%s) - failing auth\n",
- user));
- result = NT_STATUS_INVALID_PARAMETER;
- goto done;
- }
-
- DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
- domain, user));
-
- if (lp_allow_trusted_domains() && (state->request.data.auth_crap.flags & WINBIND_PAM_CONTACT_TRUSTDOM)) {
- contact_domain = domain;
- } else {
- contact_domain = lp_workgroup();
- }
-
- if (*state->request.data.auth_crap.workstation) {
- char *wrk = NULL;
- if (pull_utf8_talloc(mem_ctx, &wrk, state->request.data.auth_crap.workstation) == (size_t)-1) {
- DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
- }
- workstation = wrk;
- } else {
- workstation = lp_netbios_name();
- }
-
- if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp)
- || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) {
- DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
- state->request.data.auth_crap.lm_resp_len,
- state->request.data.auth_crap.nt_resp_len));
- result = NT_STATUS_INVALID_PARAMETER;
- goto done;
- }
-
- lm_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len);
- nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len);
-
- /*
- * Get the machine account password for the domain to contact.
- * This is either our own domain for a workstation, or possibly
- * any domain for a PDC with trusted domains.
- */
-
- if (!secrets_fetch_trust_account_password (
- contact_domain, trust_passwd, &last_change_time)) {
- DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
- "password for domain %s\n", contact_domain));
- result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- goto done;
- }
-
- ZERO_STRUCT(info3);
-
- /* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(contact_domain, trust_passwd, &cli);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", nt_errstr(result)));
- goto done;
- }
-
- result = cli_netlogon_sam_network_logon(cli, mem_ctx,
- user, domain,
- workstation, state->request.data.auth_crap.chal,
- lm_resp, nt_resp,
- &info3);
-
- if (NT_STATUS_IS_OK(result)) {
- uni_group_cache_store_netlogon(mem_ctx, &info3);
- if (state->request.data.auth_crap.flags & WINBIND_PAM_INFO3_NDR) {
- result = append_info3_as_ndr(mem_ctx, state, &info3);
- }
-
-#if 0
- /* we don't currently do this stuff right */
- /* Doing an assert in a daemon is going to be a pretty bad
- idea. - tpot */
- if (state->request.data.auth_crap.flags & WINBIND_PAM_NTKEY) {
- SMB_ASSERT(sizeof(state->response.data.auth.nt_session_key) == sizeof(info3.user_sess_key));
- memcpy(state->response.data.auth.nt_session_key, info3.user_sess_key, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
- }
- if (state->request.data.auth_crap.flags & WINBIND_PAM_LMKEY) {
- SMB_ASSERT(sizeof(state->response.data.auth.nt_session_key) <= sizeof(info3.user_sess_key));
- memcpy(state->response.data.auth.first_8_lm_hash, info3.padding, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
- }
-#endif
- }
-
-done:
-
- state->response.data.auth.nt_status = NT_STATUS_V(result);
- push_utf8_fstring(state->response.data.auth.nt_status_string, nt_errstr(result));
- push_utf8_fstring(state->response.data.auth.error_string, nt_errstr(result));
- state->response.data.auth.pam_error = nt_status_to_pam(result);
-
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
- ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n",
- domain,
- user,
- state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
-}
-
-/* Change a user password */
-
-enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
-{
- NTSTATUS result;
- char *oldpass, *newpass;
- fstring domain, user;
- CLI_POLICY_HND *hnd;
-
- DEBUG(3, ("[%5d]: pam chauthtok %s\n", state->pid,
- state->request.data.chauthtok.user));
-
- /* Setup crap */
-
- if (state == NULL)
- return WINBINDD_ERROR;
-
- if (!parse_domain_user(state->request.data.chauthtok.user, domain,
- user)) {
- result = NT_STATUS_INVALID_PARAMETER;
- goto done;
- }
-
- /* Change password */
-
- oldpass = state->request.data.chauthtok.oldpass;
- newpass = state->request.data.chauthtok.newpass;
-
- /* Get sam handle */
-
- if (!(hnd = cm_get_sam_handle(domain))) {
- DEBUG(1, ("could not get SAM handle on DC for %s\n", domain));
- result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- goto done;
- }
-
- if (!cli_oem_change_password(hnd->cli, user, newpass, oldpass)) {
- DEBUG(1, ("password change failed for user %s/%s\n", domain,
- user));
- result = NT_STATUS_WRONG_PASSWORD;
- } else {
- result = NT_STATUS_OK;
- }
-
-done:
- state->response.data.auth.nt_status = NT_STATUS_V(result);
- fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
- fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
- state->response.data.auth.pam_error = nt_status_to_pam(result);
-
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
- ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n",
- domain,
- user,
- state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
-
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
-}
diff --git a/source4/nsswitch/winbindd_rpc.c b/source4/nsswitch/winbindd_rpc.c
deleted file mode 100644
index 9989f27109..0000000000
--- a/source4/nsswitch/winbindd_rpc.c
+++ /dev/null
@@ -1,776 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind rpc backend functions
-
- Copyright (C) Tim Potter 2000-2001,2003
- Copyright (C) Andrew Tridgell 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 "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-
-/* Query display info for a domain. This returns enough information plus a
- bit extra to give an overview of domain users for the User Manager
- application. */
-static NTSTATUS query_user_list(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- WINBIND_USERINFO **info)
-{
- CLI_POLICY_HND *hnd;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- POLICY_HND dom_pol;
- BOOL got_dom_pol = False;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- unsigned int i, start_idx, retry;
-
- DEBUG(3,("rpc: query_user_list\n"));
-
- *num_entries = 0;
- *info = NULL;
-
- retry = 0;
- do {
- /* Get sam handle */
-
- if (!(hnd = cm_get_sam_handle(domain->name)))
- goto done;
-
- /* Get domain handle */
-
- result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
- des_access, &domain->sid, &dom_pol);
-
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- got_dom_pol = True;
-
- i = start_idx = 0;
- do {
- TALLOC_CTX *ctx2;
- char **dom_users;
- uint32 num_dom_users, *dom_rids, j, size = 0xffff;
- uint16 acb_mask = ACB_NORMAL;
-
- if (!(ctx2 = talloc_init("winbindd enum_users"))) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- result = cli_samr_enum_dom_users(
- hnd->cli, ctx2, &dom_pol, &start_idx, acb_mask,
- size, &dom_users, &dom_rids, &num_dom_users);
-
- *num_entries += num_dom_users;
-
- *info = talloc_realloc(
- mem_ctx, *info,
- (*num_entries) * sizeof(WINBIND_USERINFO));
-
- if (!(*info)) {
- result = NT_STATUS_NO_MEMORY;
- talloc_destroy(ctx2);
- goto done;
- }
-
- for (j = 0; j < num_dom_users; i++, j++) {
- (*info)[i].acct_name =
- talloc_strdup(mem_ctx, dom_users[j]);
- (*info)[i].full_name = talloc_strdup(mem_ctx, "");
- (*info)[i].user_sid = rid_to_talloced_sid(domain, mem_ctx, dom_rids[j]);
- /* For the moment we set the primary group for
- every user to be the Domain Users group.
- There are serious problems with determining
- the actual primary group for large domains.
- This should really be made into a 'winbind
- force group' smb.conf parameter or
- something like that. */
- (*info)[i].group_sid
- = rid_to_talloced_sid(domain,
- mem_ctx,
- DOMAIN_GROUP_RID_USERS);
- }
-
- talloc_destroy(ctx2);
-
- } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
-
- done:
-
- if (got_dom_pol)
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
-
- return result;
-}
-
-/* list all domain groups */
-static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- CLI_POLICY_HND *hnd;
- POLICY_HND dom_pol;
- NTSTATUS status;
- uint32 start = 0;
- int retry;
-
- *num_entries = 0;
- *info = NULL;
-
- DEBUG(3,("rpc: enum_dom_groups\n"));
-
- retry = 0;
- do {
- if (!(hnd = cm_get_sam_handle(domain->name)))
- return NT_STATUS_UNSUCCESSFUL;
-
- status = cli_samr_open_domain(hnd->cli, mem_ctx,
- &hnd->pol, des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- if (!NT_STATUS_IS_OK(status))
- return status;
-
- do {
- struct acct_info *info2 = NULL;
- uint32 count = 0;
- TALLOC_CTX *mem_ctx2;
-
- mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
-
- /* start is updated by this call. */
- status = cli_samr_enum_dom_groups(hnd->cli, mem_ctx2, &dom_pol,
- &start,
- 0xFFFF, /* buffer size? */
- &info2, &count);
-
- if (!NT_STATUS_IS_OK(status) &&
- !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
- talloc_destroy(mem_ctx2);
- break;
- }
-
- (*info) = talloc_realloc(mem_ctx, *info,
- sizeof(**info) * ((*num_entries) + count));
- if (! *info) {
- talloc_destroy(mem_ctx2);
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
- return NT_STATUS_NO_MEMORY;
- }
-
- memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
- (*num_entries) += count;
- talloc_destroy(mem_ctx2);
- } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
-
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
-
- return status;
-}
-
-/* List all domain groups */
-
-static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- CLI_POLICY_HND *hnd;
- POLICY_HND dom_pol;
- NTSTATUS result;
- int retry;
-
- *num_entries = 0;
- *info = NULL;
-
- retry = 0;
- do {
- if ( !(hnd = cm_get_sam_handle(domain->name)) )
- return NT_STATUS_UNSUCCESSFUL;
-
- result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol,
- des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- if ( !NT_STATUS_IS_OK(result))
- return result;
-
- do {
- struct acct_info *info2 = NULL;
- uint32 count = 0, start = *num_entries;
- TALLOC_CTX *mem_ctx2;
-
- mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
-
- result = cli_samr_enum_als_groups( hnd->cli, mem_ctx2, &dom_pol,
- &start, 0xFFFF, &info2, &count);
-
- if ( !NT_STATUS_IS_OK(result)
- && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
- {
- talloc_destroy(mem_ctx2);
- break;
- }
-
- (*info) = talloc_realloc(mem_ctx, *info,
- sizeof(**info) * ((*num_entries) + count));
- if (! *info) {
- talloc_destroy(mem_ctx2);
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
- return NT_STATUS_NO_MEMORY;
- }
-
- memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
- (*num_entries) += count;
- talloc_destroy(mem_ctx2);
- } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
-
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
-
- return result;
-}
-
-/* convert a single name to a sid in a domain */
-static NTSTATUS name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *name,
- DOM_SID *sid,
- enum SID_NAME_USE *type)
-{
- CLI_POLICY_HND *hnd;
- NTSTATUS status;
- DOM_SID *sids = NULL;
- uint32 *types = NULL;
- const char *full_name;
- int retry;
-
- DEBUG(3,("rpc: name_to_sid name=%s\n", name));
-
- full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain->name, name);
-
- if (!full_name) {
- DEBUG(0, ("talloc_asprintf failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- retry = 0;
- do {
- if (!(hnd = cm_get_lsa_handle(domain->name))) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- status = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1,
- &full_name, &sids, &types);
- } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- /* Return rid and type if lookup successful */
-
- if (NT_STATUS_IS_OK(status)) {
- sid_copy(sid, &sids[0]);
- *type = types[0];
- }
-
- return status;
-}
-
-/*
- convert a domain SID to a user or group name
-*/
-static NTSTATUS sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *sid,
- char **name,
- enum SID_NAME_USE *type)
-{
- CLI_POLICY_HND *hnd;
- char **domains;
- char **names;
- uint32 *types;
- NTSTATUS status;
- int retry;
-
- DEBUG(3,("rpc: sid_to_name\n"));
-
- retry = 0;
- do {
- if (!(hnd = cm_get_lsa_handle(domain->name)))
- return NT_STATUS_UNSUCCESSFUL;
-
- status = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
- 1, sid, &domains, &names, &types);
- } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- if (NT_STATUS_IS_OK(status)) {
- *type = types[0];
- *name = names[0];
- DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
-
- /* Paranoia */
- if (strcasecmp(domain->name, domains[0]) != 0) {
- DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0]));
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
- return status;
-}
-
-/* Lookup user information from a rid or username. */
-static NTSTATUS query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *user_sid,
- WINBIND_USERINFO *user_info)
-{
- CLI_POLICY_HND *hnd;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- POLICY_HND dom_pol, user_pol;
- BOOL got_dom_pol = False, got_user_pol = False;
- SAM_USERINFO_CTR *ctr;
- int retry;
- fstring sid_string;
- uint32 user_rid;
-
- DEBUG(3,("rpc: query_user rid=%s\n", sid_to_string(sid_string, user_sid)));
- if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
- goto done;
- }
-
- retry = 0;
- do {
- /* Get sam handle */
- if (!(hnd = cm_get_sam_handle(domain->name)))
- goto done;
-
- /* Get domain handle */
-
- result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- got_dom_pol = True;
-
- /* Get user handle */
- result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- got_user_pol = True;
-
- /* Get user info */
- result = cli_samr_query_userinfo(hnd->cli, mem_ctx, &user_pol,
- 0x15, &ctr);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- cli_samr_close(hnd->cli, mem_ctx, &user_pol);
- got_user_pol = False;
-
- user_info->user_sid = rid_to_talloced_sid(domain, mem_ctx, user_rid);
- user_info->group_sid = rid_to_talloced_sid(domain, mem_ctx, ctr->info.id21->group_rid);
- user_info->acct_name = unistr2_tdup(mem_ctx,
- &ctr->info.id21->uni_user_name);
- user_info->full_name = unistr2_tdup(mem_ctx,
- &ctr->info.id21->uni_full_name);
-
- done:
- /* Clean up policy handles */
- if (got_user_pol)
- cli_samr_close(hnd->cli, mem_ctx, &user_pol);
-
- if (got_dom_pol)
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
-
- return result;
-}
-
-/* Lookup groups a user is a member of. I wish Unix had a call like this! */
-static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *user_sid,
- uint32 *num_groups, DOM_SID ***user_gids)
-{
- CLI_POLICY_HND *hnd;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- POLICY_HND dom_pol, user_pol;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- BOOL got_dom_pol = False, got_user_pol = False;
- DOM_GID *user_groups;
- unsigned int i;
- unsigned int retry;
- fstring sid_string;
- uint32 user_rid;
-
- DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_to_string(sid_string, user_sid)));
-
- *num_groups = 0;
-
- /* First try cached universal groups from logon */
- *user_gids = uni_group_cache_fetch(&domain->sid, user_sid, mem_ctx, num_groups);
- if((*num_groups > 0) && *user_gids) {
- return NT_STATUS_OK;
- } else {
- *user_gids = NULL;
- *num_groups = 0;
- }
-
- retry = 0;
- do {
- /* Get sam handle */
- if (!(hnd = cm_get_sam_handle(domain->name)))
- goto done;
-
- /* Get domain handle */
- result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
- des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- got_dom_pol = True;
-
-
- if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
- goto done;
- }
-
- /* Get user handle */
- result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
- des_access, user_rid, &user_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- got_user_pol = True;
-
- /* Query user rids */
- result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol,
- num_groups, &user_groups);
-
- if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
- goto done;
-
- (*user_gids) = talloc(mem_ctx, sizeof(uint32) * (*num_groups));
- if (!(*user_gids)) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- for (i=0;i<(*num_groups);i++) {
- (*user_gids)[i] = rid_to_talloced_sid(domain, mem_ctx, user_groups[i].g_rid);
- }
-
- done:
- /* Clean up policy handles */
- if (got_user_pol)
- cli_samr_close(hnd->cli, mem_ctx, &user_pol);
-
- if (got_dom_pol)
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
-
- return result;
-}
-
-
-/* Lookup group membership given a rid. */
-static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *group_sid, uint32 *num_names,
- DOM_SID ***sid_mem, char ***names,
- uint32 **name_types)
-{
- CLI_POLICY_HND *hnd;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 i, total_names = 0;
- POLICY_HND dom_pol, group_pol;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- BOOL got_dom_pol = False, got_group_pol = False;
- uint32 *rid_mem = NULL;
- uint32 group_rid;
- int retry;
- unsigned int j;
- fstring sid_string;
-
- DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, sid_to_string(sid_string, group_sid)));
-
- if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) {
- goto done;
- }
-
- *num_names = 0;
-
- retry = 0;
- do {
- /* Get sam handle */
- if (!(hnd = cm_get_sam_handle(domain->name)))
- goto done;
-
- /* Get domain handle */
-
- result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
- des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- got_dom_pol = True;
-
- /* Get group handle */
-
- result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol,
- des_access, group_rid, &group_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- got_group_pol = True;
-
- /* Step #1: Get a list of user rids that are the members of the
- group. */
-
- result = cli_samr_query_groupmem(hnd->cli, mem_ctx,
- &group_pol, num_names, &rid_mem,
- name_types);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- /* Step #2: Convert list of rids into list of usernames. Do this
- in bunches of ~1000 to avoid crashing NT4. It looks like there
- is a buffer overflow or something like that lurking around
- somewhere. */
-
-#define MAX_LOOKUP_RIDS 900
-
- *names = talloc_zero(mem_ctx, *num_names * sizeof(char *));
- *name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32));
- *sid_mem = talloc_zero(mem_ctx, *num_names * sizeof(DOM_SID *));
-
- for (j=0;j<(*num_names);j++) {
- (*sid_mem)[j] = rid_to_talloced_sid(domain, mem_ctx, (rid_mem)[j]);
- }
-
- if (!*names || !*name_types) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
- int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
- uint32 tmp_num_names = 0;
- char **tmp_names = NULL;
- uint32 *tmp_types = NULL;
-
- /* Lookup a chunk of rids */
-
- result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
- &dom_pol, 1000, /* flags */
- num_lookup_rids,
- &rid_mem[i],
- &tmp_num_names,
- &tmp_names, &tmp_types);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- /* Copy result into array. The talloc system will take
- care of freeing the temporary arrays later on. */
-
- memcpy(&(*names)[i], tmp_names, sizeof(char *) *
- tmp_num_names);
-
- memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
- tmp_num_names);
-
- total_names += tmp_num_names;
- }
-
- *num_names = total_names;
-
- done:
- if (got_group_pol)
- cli_samr_close(hnd->cli, mem_ctx, &group_pol);
-
- if (got_dom_pol)
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
-
- return result;
-}
-
-/* find the sequence number for a domain */
-static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
-{
- TALLOC_CTX *mem_ctx;
- CLI_POLICY_HND *hnd;
- SAM_UNK_CTR ctr;
- uint16 switch_value = 2;
- NTSTATUS result;
- uint32 seqnum = DOM_SEQUENCE_NONE;
- POLICY_HND dom_pol;
- BOOL got_dom_pol = False;
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- int retry;
-
- DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
-
- *seq = DOM_SEQUENCE_NONE;
-
- if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
- return NT_STATUS_NO_MEMORY;
-
- retry = 0;
- do {
- /* Get sam handle */
- if (!(hnd = cm_get_sam_handle(domain->name)))
- goto done;
-
- /* Get domain handle */
- result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
- des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- got_dom_pol = True;
-
- /* Query domain info */
-
- result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
- switch_value, &ctr);
-
- if (NT_STATUS_IS_OK(result)) {
- seqnum = ctr.info.inf2.seq_num;
- DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)seqnum ));
- } else {
- DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
- (unsigned)seqnum, domain->name ));
- }
-
- done:
-
- if (got_dom_pol)
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
-
- talloc_destroy(mem_ctx);
-
- *seq = seqnum;
-
- return result;
-}
-
-/* get a list of trusted domains */
-static NTSTATUS trusted_domains(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_domains,
- char ***names,
- char ***alt_names,
- DOM_SID **dom_sids)
-{
- CLI_POLICY_HND *hnd;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 enum_ctx = 0;
- int retry;
-
- DEBUG(3,("rpc: trusted_domains\n"));
-
- *num_domains = 0;
- *alt_names = NULL;
-
- retry = 0;
- do {
- if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
- goto done;
-
- result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
- &hnd->pol, &enum_ctx,
- num_domains, names, dom_sids);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
-done:
- return result;
-}
-
-/* find the domain sid for a domain */
-static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
-{
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *mem_ctx;
- CLI_POLICY_HND *hnd;
- fstring level5_dom;
- int retry;
-
- DEBUG(3,("rpc: domain_sid\n"));
-
- if (!(mem_ctx = talloc_init("domain_sid[rpc]")))
- return NT_STATUS_NO_MEMORY;
-
- retry = 0;
- do {
- /* Get sam handle */
- if (!(hnd = cm_get_lsa_handle(domain->name)))
- goto done;
-
- status = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
- &hnd->pol, 0x05, level5_dom, sid);
- } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
-done:
- talloc_destroy(mem_ctx);
- return status;
-}
-
-/* find alternate names list for the domain - none for rpc */
-static NTSTATUS alternate_name(struct winbindd_domain *domain)
-{
- return NT_STATUS_OK;
-}
-
-
-/* the rpc backend methods are exposed via this structure */
-struct winbindd_methods msrpc_methods = {
- False,
- query_user_list,
- enum_dom_groups,
- enum_local_groups,
- name_to_sid,
- sid_to_name,
- query_user,
- lookup_usergroups,
- lookup_groupmem,
- sequence_number,
- trusted_domains,
- domain_sid,
- alternate_name
-};
diff --git a/source4/nsswitch/winbindd_sid.c b/source4/nsswitch/winbindd_sid.c
deleted file mode 100644
index 6ab2eaa646..0000000000
--- a/source4/nsswitch/winbindd_sid.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon - sid related functions
-
- Copyright (C) Tim Potter 2000
-
- 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 "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/* Convert a string */
-
-enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state)
-{
- extern DOM_SID global_sid_Builtin;
- enum SID_NAME_USE type;
- DOM_SID sid, tmp_sid;
- uint32 rid;
- fstring name;
- fstring dom_name;
-
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
-
- DEBUG(3, ("[%5d]: lookupsid %s\n", state->pid,
- state->request.data.sid));
-
- /* Lookup sid from PDC using lsa_lookup_sids() */
-
- if (!string_to_sid(&sid, state->request.data.sid)) {
- DEBUG(5, ("%s not a SID\n", state->request.data.sid));
- return WINBINDD_ERROR;
- }
-
- /* Don't look up BUILTIN sids */
-
- sid_copy(&tmp_sid, &sid);
- sid_split_rid(&tmp_sid, &rid);
-
- if (sid_equal(&tmp_sid, &global_sid_Builtin)) {
- return WINBINDD_ERROR;
- }
-
- /* Lookup the sid */
-
- if (!winbindd_lookup_name_by_sid(&sid, dom_name, name, &type)) {
- return WINBINDD_ERROR;
- }
-
- fstrcpy(state->response.data.name.dom_name, dom_name);
- fstrcpy(state->response.data.name.name, name);
-
- state->response.data.name.type = type;
-
- return WINBINDD_OK;
-}
-
-
-/**
- * Look up the SID for a qualified name.
- **/
-enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
-{
- enum SID_NAME_USE type;
- fstring sid_str;
- char *name_domain, *name_user;
- DOM_SID sid;
- struct winbindd_domain *domain;
-
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.name.dom_name)-1]='\0';
-
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0';
-
- DEBUG(3, ("[%5d]: lookupname %s%s%s\n", state->pid,
- state->request.data.name.dom_name,
- lp_winbind_separator(),
- state->request.data.name.name));
-
- name_domain = state->request.data.name.dom_name;
- name_user = state->request.data.name.name;
-
- if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(0, ("could not find domain entry for domain %s\n",
- name_domain));
- return WINBINDD_ERROR;
- }
-
- /* Lookup name from PDC using lsa_lookup_names() */
- if (!winbindd_lookup_sid_by_name(domain, name_user, &sid, &type)) {
- return WINBINDD_ERROR;
- }
-
- sid_to_string(sid_str, &sid);
- fstrcpy(state->response.data.sid.sid, sid_str);
- state->response.data.sid.type = type;
-
- return WINBINDD_OK;
-}
-
-/* Convert a sid to a uid. We assume we only have one rid attached to the
- sid. */
-
-enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
-{
- DOM_SID sid;
-
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
-
- DEBUG(3, ("[%5d]: sid to uid %s\n", state->pid,
- state->request.data.sid));
-
- /* Split sid into domain sid and user rid */
- if (!string_to_sid(&sid, state->request.data.sid)) {
- DEBUG(1, ("Could not get convert sid %s from string\n",
- state->request.data.sid));
- return WINBINDD_ERROR;
- }
-
- /* Find uid for this sid and return it */
- if (!winbindd_idmap_get_uid_from_sid(&sid, &state->response.data.uid)) {
- DEBUG(1, ("Could not get uid for sid %s\n",
- state->request.data.sid));
- return WINBINDD_ERROR;
- }
-
- return WINBINDD_OK;
-}
-
-/* Convert a sid to a gid. We assume we only have one rid attached to the
- sid.*/
-
-enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
-{
- DOM_SID sid;
-
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
-
- DEBUG(3, ("[%5d]: sid to gid %s\n", state->pid,
- state->request.data.sid));
-
- if (!string_to_sid(&sid, state->request.data.sid)) {
- DEBUG(1, ("Could not cvt string to sid %s\n",
- state->request.data.sid));
- return WINBINDD_ERROR;
- }
-
- /* Find gid for this sid and return it */
- if (!winbindd_idmap_get_gid_from_sid(&sid, &state->response.data.gid)) {
- DEBUG(1, ("Could not get gid for sid %s\n",
- state->request.data.sid));
- return WINBINDD_ERROR;
- }
-
- return WINBINDD_OK;
-}
-
-/* Convert a uid to a sid */
-
-enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state)
-{
- DOM_SID sid;
-
- /* Bug out if the uid isn't in the winbind range */
-
- if ((state->request.data.uid < server_state.uid_low ) ||
- (state->request.data.uid > server_state.uid_high)) {
- return WINBINDD_ERROR;
- }
-
- DEBUG(3, ("[%5d]: uid to sid %d\n", state->pid,
- state->request.data.uid));
-
- /* Lookup rid for this uid */
- if (!winbindd_idmap_get_sid_from_uid(state->request.data.uid, &sid)) {
- DEBUG(1, ("Could not convert uid %d to rid\n",
- state->request.data.uid));
- return WINBINDD_ERROR;
- }
-
- sid_to_string(state->response.data.sid.sid, &sid);
- state->response.data.sid.type = SID_NAME_USER;
-
- return WINBINDD_OK;
-}
-
-/* Convert a gid to a sid */
-
-enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state)
-{
- DOM_SID sid;
-
- /* Bug out if the gid isn't in the winbind range */
-
- if ((state->request.data.gid < server_state.gid_low) ||
- (state->request.data.gid > server_state.gid_high)) {
- return WINBINDD_ERROR;
- }
-
- DEBUG(3, ("[%5d]: gid to sid %d\n", state->pid,
- state->request.data.gid));
-
- /* Lookup sid for this uid */
- if (!winbindd_idmap_get_sid_from_gid(state->request.data.gid, &sid)) {
- DEBUG(1, ("Could not convert gid %d to sid\n",
- state->request.data.gid));
- return WINBINDD_ERROR;
- }
-
- /* Construct sid and return it */
- sid_to_string(state->response.data.sid.sid, &sid);
- state->response.data.sid.type = SID_NAME_DOM_GRP;
-
- return WINBINDD_OK;
-}
diff --git a/source4/nsswitch/winbindd_user.c b/source4/nsswitch/winbindd_user.c
deleted file mode 100644
index ee05543d30..0000000000
--- a/source4/nsswitch/winbindd_user.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon - user related functions
-
- Copyright (C) Tim Potter 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 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 "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/* Fill a pwent structure with information we have obtained */
-
-static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
- DOM_SID *user_sid, DOM_SID *group_sid,
- char *full_name, struct winbindd_pw *pw)
-{
- extern userdom_struct current_user_info;
- fstring output_username;
- pstring homedir;
- fstring sid_string;
-
- if (!pw || !dom_name || !user_name)
- return False;
-
- /* Resolve the uid number */
-
- if (!winbindd_idmap_get_uid_from_sid(user_sid,
- &pw->pw_uid)) {
- DEBUG(1, ("error getting user id for sid %s\n", sid_to_string(sid_string, user_sid)));
- return False;
- }
-
- /* Resolve the gid number */
-
- if (!winbindd_idmap_get_gid_from_sid(group_sid,
- &pw->pw_gid)) {
- DEBUG(1, ("error getting group id for sid %s\n", sid_to_string(sid_string, group_sid)));
- return False;
- }
-
- /* Username */
-
- fill_domain_username(output_username, dom_name, user_name);
-
- safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1);
-
- /* Full name (gecos) */
-
- safe_strcpy(pw->pw_gecos, full_name, sizeof(pw->pw_gecos) - 1);
-
- /* Home directory and shell - use template config parameters. The
- defaults are /tmp for the home directory and /bin/false for
- shell. */
-
- /* The substitution of %U and %D in the 'template homedir' is done
- by lp_string() calling standard_sub_basic(). */
-
- fstrcpy(current_user_info.smb_name, user_name);
- sub_set_smb_name(user_name);
- fstrcpy(current_user_info.domain, dom_name);
-
- pstrcpy(homedir, lp_template_homedir());
-
- safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1);
-
- safe_strcpy(pw->pw_shell, lp_template_shell(),
- sizeof(pw->pw_shell) - 1);
-
- /* Password - set to "x" as we can't generate anything useful here.
- Authentication can be done using the pam_winbind module. */
-
- safe_strcpy(pw->pw_passwd, "x", sizeof(pw->pw_passwd) - 1);
-
- return True;
-}
-
-/* Return a password structure from a username. */
-
-enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
-{
- WINBIND_USERINFO user_info;
- DOM_SID user_sid;
- NTSTATUS status;
- fstring name_domain, name_user;
- enum SID_NAME_USE name_type;
- struct winbindd_domain *domain;
- TALLOC_CTX *mem_ctx;
-
- /* Ensure null termination */
- state->request.data.username[sizeof(state->request.data.username)-1]='\0';
-
- DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid,
- state->request.data.username));
-
- /* Parse domain and username */
-
- if (!parse_domain_user(state->request.data.username, name_domain,
- name_user))
- return WINBINDD_ERROR;
-
- if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(5, ("no such domain: %s\n", name_domain));
- return WINBINDD_ERROR;
- }
-
- /* Get rid and name type from name */
-
- if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid, &name_type)) {
- DEBUG(1, ("user '%s' does not exist\n", name_user));
- return WINBINDD_ERROR;
- }
-
- if (name_type != SID_NAME_USER) {
- DEBUG(1, ("name '%s' is not a user name: %d\n", name_user,
- name_type));
- return WINBINDD_ERROR;
- }
-
- /* Get some user info. Split the user rid from the sid obtained
- from the winbind_lookup_by_name() call and use it in a
- winbind_lookup_userinfo() */
-
- if (!(mem_ctx = talloc_init("winbindd_getpwnam([%s]\\[%s])",
- name_domain, name_user))) {
- DEBUG(1, ("out of memory\n"));
- return WINBINDD_ERROR;
- }
-
- status = domain->methods->query_user(domain, mem_ctx, &user_sid,
- &user_info);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("error getting user info for user '[%s]\\[%s]'\n",
- name_domain, name_user));
- talloc_destroy(mem_ctx);
- return WINBINDD_ERROR;
- }
-
- /* Now take all this information and fill in a passwd structure */
- if (!winbindd_fill_pwent(name_domain, name_user,
- user_info.user_sid, user_info.group_sid,
- user_info.full_name,
- &state->response.data.pw)) {
- talloc_destroy(mem_ctx);
- return WINBINDD_ERROR;
- }
-
- talloc_destroy(mem_ctx);
-
- return WINBINDD_OK;
-}
-
-/* Return a password structure given a uid number */
-
-enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
-{
- DOM_SID user_sid;
- struct winbindd_domain *domain;
- fstring dom_name;
- fstring user_name;
- enum SID_NAME_USE name_type;
- WINBIND_USERINFO user_info;
- gid_t gid;
- TALLOC_CTX *mem_ctx;
- NTSTATUS status;
-
- /* Bug out if the uid isn't in the winbind range */
-
- if ((state->request.data.uid < server_state.uid_low ) ||
- (state->request.data.uid > server_state.uid_high))
- return WINBINDD_ERROR;
-
- DEBUG(3, ("[%5d]: getpwuid %d\n", state->pid,
- state->request.data.uid));
-
- /* Get rid from uid */
-
- if (!winbindd_idmap_get_sid_from_uid(state->request.data.uid,
- &user_sid)) {
- DEBUG(1, ("could not convert uid %d to SID\n",
- state->request.data.uid));
- return WINBINDD_ERROR;
- }
-
- /* Get name and name type from rid */
-
- if (!winbindd_lookup_name_by_sid(&user_sid, dom_name, user_name, &name_type)) {
- fstring temp;
-
- sid_to_string(temp, &user_sid);
- DEBUG(1, ("could not lookup sid %s\n", temp));
- return WINBINDD_ERROR;
- }
-
- domain = find_domain_from_sid(&user_sid);
-
- if (!domain) {
- DEBUG(1,("Can't find domain from sid\n"));
- return WINBINDD_ERROR;
- }
-
- /* Get some user info */
-
- if (!(mem_ctx = talloc_init("winbind_getpwuid(%d)",
- state->request.data.uid))) {
-
- DEBUG(1, ("out of memory\n"));
- return WINBINDD_ERROR;
- }
-
- status = domain->methods->query_user(domain, mem_ctx, &user_sid,
- &user_info);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("error getting user info for user '%s'\n",
- user_name));
- talloc_destroy(mem_ctx);
- return WINBINDD_ERROR;
- }
-
- /* Resolve gid number */
-
- if (!winbindd_idmap_get_gid_from_sid(user_info.group_sid, &gid)) {
- DEBUG(1, ("error getting group id for user %s\n", user_name));
- talloc_destroy(mem_ctx);
- return WINBINDD_ERROR;
- }
-
- /* Fill in password structure */
-
- if (!winbindd_fill_pwent(domain->name, user_name, user_info.user_sid,
- user_info.group_sid,
- user_info.full_name, &state->response.data.pw)) {
- talloc_destroy(mem_ctx);
- return WINBINDD_ERROR;
- }
-
- talloc_destroy(mem_ctx);
-
- return WINBINDD_OK;
-}
-
-/*
- * set/get/endpwent functions
- */
-
-/* Rewind file pointer for ntdom passwd database */
-
-enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
-{
- struct winbindd_domain *domain;
-
- DEBUG(3, ("[%5d]: setpwent\n", state->pid));
-
- /* Check user has enabled this */
-
- if (!lp_winbind_enum_users())
- return WINBINDD_ERROR;
-
- /* Free old static data if it exists */
-
- if (state->getpwent_state != NULL) {
- free_getent_state(state->getpwent_state);
- state->getpwent_state = NULL;
- }
-
- /* Create sam pipes for each domain we know about */
-
- for(domain = domain_list(); domain != NULL; domain = domain->next) {
- struct getent_state *domain_state;
-
- /* Create a state record for this domain */
-
- if ((domain_state = (struct getent_state *)
- malloc(sizeof(struct getent_state))) == NULL)
- return WINBINDD_ERROR;
-
- ZERO_STRUCTP(domain_state);
-
- fstrcpy(domain_state->domain_name, domain->name);
-
- /* Add to list of open domains */
-
- DLIST_ADD(state->getpwent_state, domain_state);
- }
-
- return WINBINDD_OK;
-}
-
-/* Close file pointer to ntdom passwd database */
-
-enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state)
-{
- DEBUG(3, ("[%5d]: endpwent\n", state->pid));
-
- free_getent_state(state->getpwent_state);
- state->getpwent_state = NULL;
-
- return WINBINDD_OK;
-}
-
-/* Get partial list of domain users for a domain. We fill in the sam_entries,
- and num_sam_entries fields with domain user information. The dispinfo_ndx
- field is incremented to the index of the next user to fetch. Return True if
- some users were returned, False otherwise. */
-
-#define MAX_FETCH_SAM_ENTRIES 100
-
-static BOOL get_sam_user_entries(struct getent_state *ent)
-{
- NTSTATUS status;
- uint32 num_entries;
- WINBIND_USERINFO *info;
- struct getpwent_user *name_list = NULL;
- BOOL result = False;
- TALLOC_CTX *mem_ctx;
- struct winbindd_domain *domain;
- struct winbindd_methods *methods;
- unsigned int i;
-
- if (ent->num_sam_entries)
- return False;
-
- if (!(mem_ctx = talloc_init("get_sam_user_entries(%s)",
- ent->domain_name)))
- return False;
-
- if (!(domain = find_domain_from_name(ent->domain_name))) {
- DEBUG(3, ("no such domain %s in get_sam_user_entries\n",
- ent->domain_name));
- return False;
- }
-
- methods = domain->methods;
-
- /* Free any existing user info */
-
- SAFE_FREE(ent->sam_entries);
- ent->num_sam_entries = 0;
-
- /* Call query_user_list to get a list of usernames and user rids */
-
- num_entries = 0;
-
- status = methods->query_user_list(domain, mem_ctx, &num_entries,
- &info);
-
- if (num_entries) {
- struct getpwent_user *tnl;
-
- tnl = (struct getpwent_user *)Realloc(name_list,
- sizeof(struct getpwent_user) *
- (ent->num_sam_entries +
- num_entries));
-
- if (!tnl) {
- DEBUG(0,("get_sam_user_entries realloc failed.\n"));
- SAFE_FREE(name_list);
- goto done;
- } else
- name_list = tnl;
- }
-
- for (i = 0; i < num_entries; i++) {
- /* Store account name and gecos */
- if (!info[i].acct_name) {
- fstrcpy(name_list[ent->num_sam_entries + i].name, "");
- } else {
- fstrcpy(name_list[ent->num_sam_entries + i].name,
- info[i].acct_name);
- }
- if (!info[i].full_name) {
- fstrcpy(name_list[ent->num_sam_entries + i].gecos, "");
- } else {
- fstrcpy(name_list[ent->num_sam_entries + i].gecos,
- info[i].full_name);
- }
-
- /* User and group ids */
- sid_copy(&name_list[ent->num_sam_entries+i].user_sid, info[i].user_sid);
- sid_copy(&name_list[ent->num_sam_entries+i].group_sid, info[i].group_sid);
- }
-
- ent->num_sam_entries += num_entries;
-
- /* Fill in remaining fields */
-
- ent->sam_entries = name_list;
- ent->sam_entry_index = 0;
- result = ent->num_sam_entries > 0;
-
- done:
-
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-/* Fetch next passwd entry from ntdom database */
-
-#define MAX_GETPWENT_USERS 500
-
-enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
-{
- struct getent_state *ent;
- struct winbindd_pw *user_list;
- int num_users, user_list_ndx = 0, i;
-
- DEBUG(3, ("[%5d]: getpwent\n", state->pid));
-
- /* Check user has enabled this */
-
- if (!lp_winbind_enum_users())
- return WINBINDD_ERROR;
-
- /* Allocate space for returning a chunk of users */
-
- num_users = MIN(MAX_GETPWENT_USERS, state->request.data.num_entries);
-
- if ((state->response.extra_data =
- malloc(num_users * sizeof(struct winbindd_pw))) == NULL)
- return WINBINDD_ERROR;
-
- memset(state->response.extra_data, 0, num_users *
- sizeof(struct winbindd_pw));
-
- user_list = (struct winbindd_pw *)state->response.extra_data;
-
- if (!(ent = state->getpwent_state))
- return WINBINDD_ERROR;
-
- /* Start sending back users */
-
- for (i = 0; i < num_users; i++) {
- struct getpwent_user *name_list = NULL;
- fstring domain_user_name;
- uint32 result;
-
- /* Do we need to fetch another chunk of users? */
-
- if (ent->num_sam_entries == ent->sam_entry_index) {
-
- while(ent && !get_sam_user_entries(ent)) {
- struct getent_state *next_ent;
-
- /* Free state information for this domain */
-
- SAFE_FREE(ent->sam_entries);
-
- next_ent = ent->next;
- DLIST_REMOVE(state->getpwent_state, ent);
-
- SAFE_FREE(ent);
- ent = next_ent;
- }
-
- /* No more domains */
-
- if (!ent)
- break;
- }
-
- name_list = ent->sam_entries;
-
- /* Skip machine accounts */
-
- if (name_list[ent->sam_entry_index].
- name[strlen(name_list[ent->sam_entry_index].name) - 1]
- == '$') {
- ent->sam_entry_index++;
- continue;
- }
-
- /* Lookup user info */
-
- result = winbindd_fill_pwent(
- ent->domain_name,
- name_list[ent->sam_entry_index].name,
- &name_list[ent->sam_entry_index].user_sid,
- &name_list[ent->sam_entry_index].group_sid,
- name_list[ent->sam_entry_index].gecos,
- &user_list[user_list_ndx]);
-
- ent->sam_entry_index++;
-
- /* Add user to return list */
-
- if (result) {
-
- user_list_ndx++;
- state->response.data.num_entries++;
- state->response.length +=
- sizeof(struct winbindd_pw);
-
- } else
- DEBUG(1, ("could not lookup domain user %s\n",
- domain_user_name));
- }
-
- /* Out of domains */
-
- return (user_list_ndx > 0) ? WINBINDD_OK : WINBINDD_ERROR;
-}
-
-/* List domain users without mapping to unix ids */
-
-enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
-{
- struct winbindd_domain *domain;
- WINBIND_USERINFO *info;
- uint32 num_entries = 0, total_entries = 0;
- char *ted, *extra_data = NULL;
- int extra_data_len = 0;
- TALLOC_CTX *mem_ctx;
- enum winbindd_result rv = WINBINDD_ERROR;
-
- DEBUG(3, ("[%5d]: list users\n", state->pid));
-
- if (!(mem_ctx = talloc_init("winbindd_list_users")))
- return WINBINDD_ERROR;
-
- /* Enumerate over trusted domains */
-
- for (domain = domain_list(); domain; domain = domain->next) {
- NTSTATUS status;
- struct winbindd_methods *methods;
- unsigned int i;
-
- methods = domain->methods;
-
- /* Query display info */
- status = methods->query_user_list(domain, mem_ctx,
- &num_entries, &info);
-
- if (num_entries == 0)
- continue;
-
- /* Allocate some memory for extra data */
- total_entries += num_entries;
-
- ted = Realloc(extra_data, sizeof(fstring) * total_entries);
-
- if (!ted) {
- DEBUG(0,("failed to enlarge buffer!\n"));
- SAFE_FREE(extra_data);
- goto done;
- } else
- extra_data = ted;
-
- /* Pack user list into extra data fields */
-
- for (i = 0; i < num_entries; i++) {
- fstring acct_name, name;
-
- if (!info[i].acct_name) {
- fstrcpy(acct_name, "");
- } else {
- fstrcpy(acct_name, info[i].acct_name);
- }
-
- fill_domain_username(name, domain->name, acct_name);
-
- /* Append to extra data */
- memcpy(&extra_data[extra_data_len], name,
- strlen(name));
- extra_data_len += strlen(name);
- extra_data[extra_data_len++] = ',';
- }
- }
-
- /* Assign extra_data fields in response structure */
-
- if (extra_data) {
- extra_data[extra_data_len - 1] = '\0';
- state->response.extra_data = extra_data;
- state->response.length += extra_data_len;
- }
-
- /* No domains responded but that's still OK so don't return an
- error. */
-
- rv = WINBINDD_OK;
-
- done:
-
- talloc_destroy(mem_ctx);
-
- return rv;
-}
diff --git a/source4/nsswitch/winbindd_util.c b/source4/nsswitch/winbindd_util.c
deleted file mode 100644
index 7ccf032041..0000000000
--- a/source4/nsswitch/winbindd_util.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000-2001
- Copyright (C) 2001 by Martin Pool <mbp@samba.org>
-
- 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 "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/**
- * @file winbindd_util.c
- *
- * Winbind daemon for NT domain authentication nss module.
- **/
-
-
-/**
- * Used to clobber name fields that have an undefined value.
- *
- * Correct code should never look at a field that has this value.
- **/
-
-static const fstring name_deadbeef = "<deadbeef>";
-
-/* The list of trusted domains. Note that the list can be deleted and
- recreated using the init_domain_list() function so pointers to
- individual winbindd_domain structures cannot be made. Keep a copy of
- the domain name instead. */
-
-static struct winbindd_domain *_domain_list;
-
-struct winbindd_domain *domain_list(void)
-{
- /* Initialise list */
-
- if (!_domain_list)
- init_domain_list();
-
- return _domain_list;
-}
-
-/* Free all entries in the trusted domain list */
-
-void free_domain_list(void)
-{
- struct winbindd_domain *domain = _domain_list;
-
- while(domain) {
- struct winbindd_domain *next = domain->next;
-
- DLIST_REMOVE(_domain_list, domain);
- SAFE_FREE(domain);
- domain = next;
- }
-}
-
-
-/* Add a trusted domain to our list of domains */
-static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
- struct winbindd_methods *methods,
- DOM_SID *sid)
-{
- struct winbindd_domain *domain;
-
- /* We can't call domain_list() as this function is called from
- init_domain_list() and we'll get stuck in a loop. */
- for (domain = _domain_list; domain; domain = domain->next) {
- if (strcasecmp(domain_name, domain->name) == 0 ||
- strcasecmp(domain_name, domain->alt_name) == 0) {
- return domain;
- }
- if (alt_name && *alt_name) {
- if (strcasecmp(alt_name, domain->name) == 0 ||
- strcasecmp(alt_name, domain->alt_name) == 0) {
- return domain;
- }
- }
- }
-
- /* Create new domain entry */
-
- if ((domain = (struct winbindd_domain *)
- malloc(sizeof(*domain))) == NULL)
- return NULL;
-
- /* Fill in fields */
-
- ZERO_STRUCTP(domain);
-
- /* prioritise the short name */
- if (strchr_m(domain_name, '.') && alt_name && *alt_name) {
- fstrcpy(domain->name, alt_name);
- fstrcpy(domain->alt_name, domain_name);
- } else {
- fstrcpy(domain->name, domain_name);
- if (alt_name) {
- fstrcpy(domain->alt_name, alt_name);
- }
- }
-
- domain->methods = methods;
- domain->sequence_number = DOM_SEQUENCE_NONE;
- domain->last_seq_check = 0;
- if (sid) {
- sid_copy(&domain->sid, sid);
- }
-
- /* see if this is a native mode win2k domain, but only for our own domain */
-
- if ( strequal( lp_workgroup(), domain_name) ) {
- domain->native_mode = cm_check_for_native_mode_win2k( domain_name );
- DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain_name,
- domain->native_mode ? "native" : "mixed" ));
- }
-
- /* Link to domain list */
- DLIST_ADD(_domain_list, domain);
-
- DEBUG(1,("Added domain %s %s %s\n",
- domain->name, domain->alt_name,
- sid?sid_string_static(&domain->sid):""));
-
- return domain;
-}
-
-
-/*
- rescan our domains looking for new trusted domains
- */
-void rescan_trusted_domains(BOOL force)
-{
- struct winbindd_domain *domain;
- TALLOC_CTX *mem_ctx;
- static time_t last_scan;
- time_t t = time(NULL);
-
- /* trusted domains might be disabled */
- if (!lp_allow_trusted_domains()) {
- return;
- }
-
- /* Only rescan every few minutes but force if necessary */
-
- if (((unsigned)(t - last_scan) < WINBINDD_RESCAN_FREQ) && !force)
- return;
-
- last_scan = t;
-
- DEBUG(1, ("scanning trusted domain list\n"));
-
- if (!(mem_ctx = talloc_init("init_domain_list")))
- return;
-
- for (domain = _domain_list; domain; domain = domain->next) {
- NTSTATUS result;
- char **names;
- char **alt_names;
- int num_domains = 0;
- DOM_SID *dom_sids;
- int i;
-
- result = domain->methods->trusted_domains(domain, mem_ctx, &num_domains,
- &names, &alt_names, &dom_sids);
- if (!NT_STATUS_IS_OK(result)) {
- continue;
- }
-
- /* Add each domain to the trusted domain list. Each domain inherits
- the access methods of its parent */
- for(i = 0; i < num_domains; i++) {
- DEBUG(10,("Found domain %s\n", names[i]));
- add_trusted_domain(names[i], alt_names?alt_names[i]:NULL,
- domain->methods, &dom_sids[i]);
-
- /* store trusted domain in the cache */
- trustdom_cache_store(mem_ctx, names[i], alt_names ? alt_names[i] : NULL,
- &dom_sids[i], t + WINBINDD_RESCAN_FREQ);
- }
- }
-
- talloc_destroy(mem_ctx);
-}
-
-/* Look up global info for the winbind daemon */
-BOOL init_domain_list(void)
-{
- extern struct winbindd_methods cache_methods;
- struct winbindd_domain *domain;
-
- /* Free existing list */
- free_domain_list();
-
- /* Add ourselves as the first entry */
- domain = add_trusted_domain(lp_workgroup(), NULL, &cache_methods, NULL);
- if (!secrets_fetch_domain_sid(domain->name, &domain->sid)) {
- DEBUG(1, ("Could not fetch sid for our domain %s\n",
- domain->name));
- return False;
- }
-
- /* get any alternate name for the primary domain */
- cache_methods.alternate_name(domain);
-
- /* do an initial scan for trusted domains */
- rescan_trusted_domains(True);
-
- return True;
-}
-
-/* Given a domain name, return the struct winbindd domain info for it
- if it is actually working. */
-
-struct winbindd_domain *find_domain_from_name(const char *domain_name)
-{
- struct winbindd_domain *domain;
-
- /* Search through list */
-
- for (domain = domain_list(); domain != NULL; domain = domain->next) {
- if (strequal(domain_name, domain->name) ||
- (domain->alt_name[0] && strequal(domain_name, domain->alt_name)))
- return domain;
- }
-
- /* Not found */
-
- return NULL;
-}
-
-/* Given a domain sid, return the struct winbindd domain info for it */
-
-struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
-{
- struct winbindd_domain *domain;
-
- /* Search through list */
-
- for (domain = domain_list(); domain != NULL; domain = domain->next) {
- if (sid_compare_domain(sid, &domain->sid) == 0)
- return domain;
- }
-
- /* Not found */
-
- return NULL;
-}
-
-/* Lookup a sid in a domain from a name */
-
-BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
- const char *name, DOM_SID *sid,
- enum SID_NAME_USE *type)
-{
- NTSTATUS result;
- TALLOC_CTX *mem_ctx;
- /* Don't bother with machine accounts */
-
- if (name[strlen(name) - 1] == '$')
- return False;
-
- mem_ctx = talloc_init("lookup_sid_by_name for %s\n", name);
- if (!mem_ctx)
- return False;
-
- /* Lookup name */
- result = domain->methods->name_to_sid(domain, mem_ctx, name, sid, type);
-
- talloc_destroy(mem_ctx);
-
- /* Return rid and type if lookup successful */
- if (!NT_STATUS_IS_OK(result)) {
- *type = SID_NAME_UNKNOWN;
- }
-
- return NT_STATUS_IS_OK(result);
-}
-
-/**
- * @brief Lookup a name in a domain from a sid.
- *
- * @param sid Security ID you want to look up.
- *
- * @param name On success, set to the name corresponding to @p sid.
- *
- * @param dom_name On success, set to the 'domain name' corresponding to @p sid.
- *
- * @param type On success, contains the type of name: alias, group or
- * user.
- *
- * @retval True if the name exists, in which case @p name and @p type
- * are set, otherwise False.
- **/
-BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
- fstring dom_name,
- fstring name,
- enum SID_NAME_USE *type)
-{
- char *names;
- NTSTATUS result;
- TALLOC_CTX *mem_ctx;
- BOOL rv = False;
- struct winbindd_domain *domain;
-
- domain = find_domain_from_sid(sid);
-
- if (!domain) {
- DEBUG(1,("Can't find domain from sid\n"));
- return False;
- }
-
- /* Lookup name */
-
- if (!(mem_ctx = talloc_init("winbindd_lookup_name_by_sid")))
- return False;
-
- result = domain->methods->sid_to_name(domain, mem_ctx, sid, &names, type);
-
- /* Return name and type if successful */
-
- if ((rv = NT_STATUS_IS_OK(result))) {
- fstrcpy(dom_name, domain->name);
- fstrcpy(name, names);
- } else {
- *type = SID_NAME_UNKNOWN;
- fstrcpy(name, name_deadbeef);
- }
-
- talloc_destroy(mem_ctx);
-
- return rv;
-}
-
-
-/* Free state information held for {set,get,end}{pw,gr}ent() functions */
-
-void free_getent_state(struct getent_state *state)
-{
- struct getent_state *temp;
-
- /* Iterate over state list */
-
- temp = state;
-
- while(temp != NULL) {
- struct getent_state *next;
-
- /* Free sam entries then list entry */
-
- SAFE_FREE(state->sam_entries);
- DLIST_REMOVE(state, state);
- next = temp->next;
-
- SAFE_FREE(temp);
- temp = next;
- }
-}
-
-/* Parse winbindd related parameters */
-
-BOOL winbindd_param_init(void)
-{
- /* Parse winbind uid and winbind_gid parameters */
-
- if (!lp_winbind_uid(&server_state.uid_low, &server_state.uid_high)) {
- DEBUG(0, ("winbind uid range missing or invalid\n"));
- return False;
- }
-
- if (!lp_winbind_gid(&server_state.gid_low, &server_state.gid_high)) {
- DEBUG(0, ("winbind gid range missing or invalid\n"));
- return False;
- }
-
- return True;
-}
-
-/* Check if a domain is present in a comma-separated list of domains */
-
-BOOL check_domain_env(char *domain_env, char *domain)
-{
- fstring name;
- const char *tmp = domain_env;
-
- while(next_token(&tmp, name, ",", sizeof(fstring))) {
- if (strequal(name, domain))
- return True;
- }
-
- return False;
-}
-
-/* Parse a string of the form DOMAIN/user into a domain and a user */
-
-BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
-{
- char *p = strchr(domuser,*lp_winbind_separator());
-
- if (!(p || lp_winbind_use_default_domain()))
- return False;
-
- if(!p && lp_winbind_use_default_domain()) {
- fstrcpy(user, domuser);
- fstrcpy(domain, lp_workgroup());
- } else {
- fstrcpy(user, p+1);
- fstrcpy(domain, domuser);
- domain[PTR_DIFF(p, domuser)] = 0;
- }
- strupper(domain);
- return True;
-}
-
-/*
- Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and
- 'winbind separator' options.
- This means:
- - omit DOMAIN when 'winbind use default domain = true' and DOMAIN is
- lp_workgroup
-
-*/
-void fill_domain_username(fstring name, const char *domain, const char *user)
-{
- if(lp_winbind_use_default_domain() &&
- !strcmp(lp_workgroup(), domain)) {
- strlcpy(name, user, sizeof(fstring));
- } else {
- slprintf(name, sizeof(fstring) - 1, "%s%s%s",
- domain, lp_winbind_separator(),
- user);
- }
-}
-
-/*
- * Winbindd socket accessor functions
- */
-
-/* Open the winbindd socket */
-
-static int _winbindd_socket = -1;
-
-int open_winbindd_socket(void)
-{
- if (_winbindd_socket == -1) {
- _winbindd_socket = create_pipe_sock(
- WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME, 0755);
- DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",
- _winbindd_socket));
- }
-
- return _winbindd_socket;
-}
-
-/* Close the winbindd socket */
-
-void close_winbindd_socket(void)
-{
- if (_winbindd_socket != -1) {
- DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
- _winbindd_socket));
- close(_winbindd_socket);
- _winbindd_socket = -1;
- }
-}
-
-/*
- * Client list accessor functions
- */
-
-static struct winbindd_cli_state *_client_list;
-static int _num_clients;
-
-/* Return list of all connected clients */
-
-struct winbindd_cli_state *winbindd_client_list(void)
-{
- return _client_list;
-}
-
-/* Add a connection to the list */
-
-void winbindd_add_client(struct winbindd_cli_state *cli)
-{
- DLIST_ADD(_client_list, cli);
- _num_clients++;
-}
-
-/* Remove a client from the list */
-
-void winbindd_remove_client(struct winbindd_cli_state *cli)
-{
- DLIST_REMOVE(_client_list, cli);
- _num_clients--;
-}
-
-/* Close all open clients */
-
-void winbindd_kill_all_clients(void)
-{
- struct winbindd_cli_state *cl = winbindd_client_list();
-
- DEBUG(10, ("winbindd_kill_all_clients: going postal\n"));
-
- while (cl) {
- struct winbindd_cli_state *next;
-
- next = cl->next;
- winbindd_remove_client(cl);
- cl = next;
- }
-}
-
-/* Return number of open clients */
-
-int winbindd_num_clients(void)
-{
- return _num_clients;
-}
-
-/* Help with RID -> SID conversion */
-
-DOM_SID *rid_to_talloced_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 rid)
-{
- DOM_SID *sid;
- sid = talloc(mem_ctx, sizeof(*sid));
- if (!sid) {
- smb_panic("rid_to_to_talloced_sid: talloc for DOM_SID failed!\n");
- }
- sid_copy(sid, &domain->sid);
- sid_append_rid(sid, rid);
- return sid;
-}
-
diff --git a/source4/nsswitch/winbindd_wins.c b/source4/nsswitch/winbindd_wins.c
deleted file mode 100644
index 8ddd5dc10d..0000000000
--- a/source4/nsswitch/winbindd_wins.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon - WINS related functions
-
- Copyright (C) Andrew Tridgell 1999
- Copyright (C) Herb Lewis 2002
-
- 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 "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/* Use our own create socket code so we don't recurse.... */
-
-static int wins_lookup_open_socket_in(void)
-{
- struct sockaddr_in sock;
- int val=1;
- int res;
-
- memset((char *)&sock,'\0',sizeof(sock));
-
-#ifdef HAVE_SOCK_SIN_LEN
- sock.sin_len = sizeof(sock);
-#endif
- sock.sin_port = 0;
- sock.sin_family = AF_INET;
- sock.sin_addr.s_addr = interpret_addr("0.0.0.0");
- res = socket(AF_INET, SOCK_DGRAM, 0);
- if (res == -1)
- return -1;
-
- setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val));
-#ifdef SO_REUSEPORT
- setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val));
-#endif /* SO_REUSEPORT */
-
- /* now we've got a socket - we need to bind it */
-
- if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) {
- close(res);
- return(-1);
- }
-
- set_socket_options(res,"SO_BROADCAST");
-
- return res;
-}
-
-
-static struct node_status *lookup_byaddr_backend(char *addr, int *count)
-{
- int fd;
- struct in_addr ip;
- struct nmb_name nname;
- struct node_status *status;
-
- fd = wins_lookup_open_socket_in();
- if (fd == -1)
- return NULL;
-
- make_nmb_name(&nname, "*", 0);
- ip = *interpret_addr2(addr);
- status = node_status_query(fd,&nname,ip, count);
-
- close(fd);
- return status;
-}
-
-static struct in_addr *lookup_byname_backend(const char *name, int *count)
-{
- int fd;
- struct in_addr *ret = NULL;
- int j, flags = 0;
-
- *count = 0;
-
- /* always try with wins first */
- if (resolve_wins(name,0x20,&ret,count)) {
- return ret;
- }
-
- fd = wins_lookup_open_socket_in();
- if (fd == -1) {
- return NULL;
- }
-
- /* uggh, we have to broadcast to each interface in turn */
- for (j=iface_count() - 1;
- j >= 0;
- j--) {
- struct in_addr *bcast = iface_n_bcast(j);
- ret = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
- if (ret) break;
- }
-
- close(fd);
- return ret;
-}
-
-/* Get hostname from IP */
-
-enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
-{
- fstring response;
- int i, count, maxlen, size;
- struct node_status *status;
-
- /* Ensure null termination */
- state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
-
- DEBUG(3, ("[%5d]: wins_byip %s\n", state->pid,
- state->request.data.winsreq));
-
- *response = '\0';
- maxlen = sizeof(response) - 1;
-
- if ((status = lookup_byaddr_backend(state->request.data.winsreq, &count))){
- size = strlen(state->request.data.winsreq);
- if (size > maxlen) {
- SAFE_FREE(status);
- return WINBINDD_ERROR;
- }
- safe_strcat(response,state->request.data.winsreq,maxlen);
- safe_strcat(response,"\t",maxlen);
- for (i = 0; i < count; i++) {
- /* ignore group names */
- if (status[i].flags & 0x80) continue;
- if (status[i].type == 0x20) {
- size = sizeof(status[i].name) + strlen(response);
- if (size > maxlen) {
- SAFE_FREE(status);
- return WINBINDD_ERROR;
- }
- safe_strcat(response, status[i].name, maxlen);
- safe_strcat(response, " ", maxlen);
- }
- }
- /* make last character a newline */
- response[strlen(response)-1] = '\n';
- SAFE_FREE(status);
- }
- fstrcpy(state->response.data.winsresp,response);
- return WINBINDD_OK;
-}
-
-/* Get IP from hostname */
-
-enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
-{
- struct in_addr *ip_list;
- int i, count, maxlen, size;
- fstring response;
- char * addr;
-
- /* Ensure null termination */
- state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
-
- DEBUG(3, ("[%5d]: wins_byname %s\n", state->pid,
- state->request.data.winsreq));
-
- *response = '\0';
- maxlen = sizeof(response) - 1;
-
- if ((ip_list = lookup_byname_backend(state->request.data.winsreq,&count))){
- for (i = count; i ; i--) {
- addr = inet_ntoa(ip_list[i-1]);
- size = strlen(addr);
- if (size > maxlen) {
- SAFE_FREE(ip_list);
- return WINBINDD_ERROR;
- }
- if (i != 0) {
- /* Clear out the newline character */
- response[strlen(response)-1] = ' ';
- }
- safe_strcat(response,addr,maxlen);
- safe_strcat(response,"\t",maxlen);
- }
- size = strlen(state->request.data.winsreq) + strlen(response);
- if (size > maxlen) {
- SAFE_FREE(ip_list);
- return WINBINDD_ERROR;
- }
- safe_strcat(response,state->request.data.winsreq,maxlen);
- safe_strcat(response,"\n",maxlen);
- SAFE_FREE(ip_list);
- } else
- return WINBINDD_ERROR;
-
- fstrcpy(state->response.data.winsresp,response);
-
- return WINBINDD_OK;
-}
diff --git a/source4/nsswitch/wins.c b/source4/nsswitch/wins.c
deleted file mode 100644
index d5791d7af5..0000000000
--- a/source4/nsswitch/wins.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- a WINS nsswitch module
- Copyright (C) Andrew Tridgell 1999
-
- 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 HAVE_NS_API_H
-#undef VOLATILE
-
-#include <ns_daemon.h>
-#endif
-
-#ifndef INADDRSZ
-#define INADDRSZ 4
-#endif
-
-static int initialised;
-
-extern BOOL AllowDebugChange;
-
-/* Use our own create socket code so we don't recurse.... */
-
-static int wins_lookup_open_socket_in(void)
-{
- struct sockaddr_in sock;
- int val=1;
- int res;
-
- memset((char *)&sock,'\0',sizeof(sock));
-
-#ifdef HAVE_SOCK_SIN_LEN
- sock.sin_len = sizeof(sock);
-#endif
- sock.sin_port = 0;
- sock.sin_family = AF_INET;
- sock.sin_addr.s_addr = interpret_addr("0.0.0.0");
- res = socket(AF_INET, SOCK_DGRAM, 0);
- if (res == -1)
- return -1;
-
- setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val));
-#ifdef SO_REUSEPORT
- setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val));
-#endif /* SO_REUSEPORT */
-
- /* now we've got a socket - we need to bind it */
-
- if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) {
- close(res);
- return(-1);
- }
-
- set_socket_options(res,"SO_BROADCAST");
-
- return res;
-}
-
-
-static void nss_wins_init(void)
-{
- initialised = 1;
- DEBUGLEVEL = 0;
- AllowDebugChange = False;
-
- TimeInit();
- setup_logging("nss_wins",DEBUG_FILE);
- lp_load(dyn_CONFIGFILE,True,False,False);
- load_interfaces();
-}
-
-static struct node_status *lookup_byaddr_backend(char *addr, int *count)
-{
- int fd;
- struct in_addr ip;
- struct nmb_name nname;
- struct node_status *status;
-
- if (!initialised) {
- nss_wins_init();
- }
-
- fd = wins_lookup_open_socket_in();
- if (fd == -1)
- return NULL;
-
- make_nmb_name(&nname, "*", 0);
- ip = *interpret_addr2(addr);
- status = node_status_query(fd,&nname,ip, count);
-
- close(fd);
- return status;
-}
-
-static struct in_addr *lookup_byname_backend(const char *name, int *count)
-{
- int fd = -1;
- struct in_addr *ret = NULL;
- struct in_addr p;
- int j, flags = 0;
-
- if (!initialised) {
- nss_wins_init();
- }
-
- *count = 0;
-
- /* always try with wins first */
- if (resolve_wins(name,0x20,&ret,count)) {
- return ret;
- }
-
- fd = wins_lookup_open_socket_in();
- if (fd == -1) {
- return NULL;
- }
-
- /* uggh, we have to broadcast to each interface in turn */
- for (j=iface_count() - 1;j >= 0;j--) {
- struct in_addr *bcast = iface_n_bcast(j);
- ret = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
- if (ret) break;
- }
-
-out:
- close(fd);
- return ret;
-}
-
-
-#ifdef HAVE_NS_API_H
-/* IRIX version */
-
-int init(void)
-{
- nsd_logprintf(NSD_LOG_MIN, "entering init (wins)\n");
- nss_wins_init();
- return NSD_OK;
-}
-
-int lookup(nsd_file_t *rq)
-{
- char *map;
- char *key;
- char *addr;
- struct in_addr *ip_list;
- struct node_status *status;
- int i, count, len, size;
- char response[1024];
- BOOL found = False;
-
- nsd_logprintf(NSD_LOG_MIN, "entering lookup (wins)\n");
- if (! rq)
- return NSD_ERROR;
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- if (! map) {
- rq->f_status = NS_FATAL;
- return NSD_ERROR;
- }
-
- key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0);
- if (! key || ! *key) {
- rq->f_status = NS_FATAL;
- return NSD_ERROR;
- }
-
- response[0] = '\0';
- len = sizeof(response) - 2;
-
- /*
- * response needs to be a string of the following format
- * ip_address[ ip_address]*\tname[ alias]*
- */
- if (strcasecmp(map,"hosts.byaddr") == 0) {
- if ( status = lookup_byaddr_backend(key, &count)) {
- size = strlen(key) + 1;
- if (size > len) {
- free(status);
- return NSD_ERROR;
- }
- len -= size;
- strncat(response,key,size);
- strncat(response,"\t",1);
- for (i = 0; i < count; i++) {
- /* ignore group names */
- if (status[i].flags & 0x80) continue;
- if (status[i].type == 0x20) {
- size = sizeof(status[i].name) + 1;
- if (size > len) {
- free(status);
- return NSD_ERROR;
- }
- len -= size;
- strncat(response, status[i].name, size);
- strncat(response, " ", 1);
- found = True;
- }
- }
- response[strlen(response)-1] = '\n';
- free(status);
- }
- } else if (strcasecmp(map,"hosts.byname") == 0) {
- if (ip_list = lookup_byname_backend(key, &count)) {
- for (i = count; i ; i--) {
- addr = inet_ntoa(ip_list[i-1]);
- size = strlen(addr) + 1;
- if (size > len) {
- free(ip_list);
- return NSD_ERROR;
- }
- len -= size;
- if (i != 0)
- response[strlen(response)-1] = ' ';
- strncat(response,addr,size);
- strncat(response,"\t",1);
- }
- size = strlen(key) + 1;
- if (size > len) {
- free(ip_list);
- return NSD_ERROR;
- }
- strncat(response,key,size);
- strncat(response,"\n",1);
- found = True;
- free(ip_list);
- }
- }
-
- if (found) {
- nsd_logprintf(NSD_LOG_LOW, "lookup (wins %s) %s\n",map,response);
- nsd_set_result(rq,NS_SUCCESS,response,strlen(response),VOLATILE);
- return NSD_OK;
- }
- nsd_logprintf(NSD_LOG_LOW, "lookup (wins) not found\n");
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
-}
-
-#else
-/****************************************************************************
-gethostbyname() - we ignore any domain portion of the name and only
-handle names that are at most 15 characters long
- **************************************************************************/
-NSS_STATUS
-_nss_wins_gethostbyname_r(const char *name, struct hostent *he,
- char *buffer, size_t buflen, int *errnop,
- int *h_errnop)
-{
- char **host_addresses;
- struct in_addr *ip_list;
- int i, count;
- size_t namelen = strlen(name) + 1;
-
- memset(he, '\0', sizeof(*he));
-
- ip_list = lookup_byname_backend(name, &count);
- if (!ip_list) {
- return NSS_STATUS_NOTFOUND;
- }
-
- if (buflen < namelen + (2*count+1)*INADDRSZ) {
- /* no ENOMEM error type?! */
- return NSS_STATUS_NOTFOUND;
- }
-
-
- host_addresses = (char **)buffer;
- he->h_addr_list = host_addresses;
- host_addresses[count] = NULL;
- buffer += (count + 1) * INADDRSZ;
- buflen += (count + 1) * INADDRSZ;
- he->h_addrtype = AF_INET;
- he->h_length = INADDRSZ;
-
- for (i=0;i<count;i++) {
- memcpy(buffer, &ip_list[i].s_addr, INADDRSZ);
- *host_addresses = buffer;
- buffer += INADDRSZ;
- buflen -= INADDRSZ;
- host_addresses++;
- }
-
- if (ip_list)
- free(ip_list);
-
- memcpy(buffer, name, namelen);
- he->h_name = buffer;
-
- return NSS_STATUS_SUCCESS;
-}
-
-
-NSS_STATUS
-_nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he,
- char *buffer, size_t buflen, int *errnop,
- int *h_errnop)
-{
- if(af!=AF_INET) {
- *h_errnop = NO_DATA;
- *errnop = EAFNOSUPPORT;
- return NSS_STATUS_UNAVAIL;
- }
-
- return _nss_wins_gethostbyname_r(name,he,buffer,buflen,errnop,h_errnop);
-}
-#endif
diff --git a/source4/printing/config.m4 b/source4/printing/config.m4
deleted file mode 100644
index ad5e4844e5..0000000000
--- a/source4/printing/config.m4
+++ /dev/null
@@ -1,16 +0,0 @@
-############################################
-# for cups support we need libcups, and a handful of header files
-
-AC_ARG_ENABLE(cups,
-[ --enable-cups Turn on CUPS support (default=auto)])
-
-if test x$enable_cups != xno; then
- AC_PATH_PROG(CUPS_CONFIG, cups-config)
-
- if test "x$CUPS_CONFIG" != x; then
- AC_DEFINE(HAVE_CUPS,1,[Whether we have CUPS])
- CFLAGS="$CFLAGS `$CUPS_CONFIG --cflags`"
- LDFLAGS="$LDFLAGS `$CUPS_CONFIG --ldflags`"
- PRINTLIBS="$PRINTLIBS `$CUPS_CONFIG --libs`"
- fi
-fi
diff --git a/source4/printing/load.c b/source4/printing/load.c
deleted file mode 100644
index cd90cbb6f3..0000000000
--- a/source4/printing/load.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- load printer lists
- Copyright (C) Andrew Tridgell 1992-2000
-
- 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"
-
-
-/***************************************************************************
-auto-load printer services
-***************************************************************************/
-void add_all_printers(void)
-{
- int printers = lp_servicenumber(PRINTERS_NAME);
-
- if (printers < 0) return;
-
- pcap_printer_fn(lp_add_one_printer);
-}
-
-/***************************************************************************
-auto-load some homes and printer services
-***************************************************************************/
-static void add_auto_printers(void)
-{
- const char *p;
- int printers;
- char *str = strdup(lp_auto_services());
-
- if (!str) return;
-
- printers = lp_servicenumber(PRINTERS_NAME);
-
- if (printers < 0) {
- SAFE_FREE(str);
- return;
- }
-
- for (p=strtok(str,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
- if (lp_servicenumber(p) >= 0) continue;
-
- if (pcap_printername_ok(p,NULL)) {
- lp_add_printer(p,printers);
- }
- }
-
- SAFE_FREE(str);
-}
-
-/***************************************************************************
-load automatic printer services
-***************************************************************************/
-void load_printers(void)
-{
- add_auto_printers();
- if (lp_load_printers())
- add_all_printers();
-}
diff --git a/source4/printing/lpq_parse.c b/source4/printing/lpq_parse.c
deleted file mode 100644
index 4b91b8ac9a..0000000000
--- a/source4/printing/lpq_parse.c
+++ /dev/null
@@ -1,1099 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- lpq parsing routines
- Copyright (C) Andrew Tridgell 2000
-
- 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 const char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
-
-
-/*******************************************************************
-process time fields
-********************************************************************/
-static time_t EntryTime(fstring tok[], int ptr, int count, int minimum)
-{
- time_t jobtime,jobtime1;
-
- jobtime = time(NULL); /* default case: take current time */
- if (count >= minimum) {
- struct tm *t;
- int i, day, hour, min, sec;
- char *c;
-
- for (i=0; i<13; i++) if (!strncmp(tok[ptr], Months[i],3)) break; /* Find month */
- if (i<12) {
- t = localtime(&jobtime);
- day = atoi(tok[ptr+1]);
- c=(char *)(tok[ptr+2]);
- *(c+2)=0;
- hour = atoi(c);
- *(c+5)=0;
- min = atoi(c+3);
- if(*(c+6) != 0)sec = atoi(c+6);
- else sec=0;
-
- if ((t->tm_mon < i)||
- ((t->tm_mon == i)&&
- ((t->tm_mday < day)||
- ((t->tm_mday == day)&&
- (t->tm_hour*60+t->tm_min < hour*60+min)))))
- t->tm_year--; /* last year's print job */
-
- t->tm_mon = i;
- t->tm_mday = day;
- t->tm_hour = hour;
- t->tm_min = min;
- t->tm_sec = sec;
- jobtime1 = mktime(t);
- if (jobtime1 != (time_t)-1)
- jobtime = jobtime1;
- }
- }
- return jobtime;
-}
-
-
-/****************************************************************************
-parse a lpq line
-
-here is an example of lpq output under bsd
-
-Warning: no daemon present
-Rank Owner Job Files Total Size
-1st tridge 148 README 8096 bytes
-
-here is an example of lpq output under osf/1
-
-Warning: no daemon present
-Rank Pri Owner Job Files Total Size
-1st 0 tridge 148 README 8096 bytes
-
-
-<allan@umich.edu> June 30, 1998.
-Modified to handle file names with spaces, like the parse_lpq_lprng code
-further below.
-****************************************************************************/
-static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
-{
-#ifdef OSF1
-#define RANKTOK 0
-#define PRIOTOK 1
-#define USERTOK 2
-#define JOBTOK 3
-#define FILETOK 4
-#define TOTALTOK (count - 2)
-#define NTOK 6
-#define MAXTOK 128
-#else /* OSF1 */
-#define RANKTOK 0
-#define USERTOK 1
-#define JOBTOK 2
-#define FILETOK 3
-#define TOTALTOK (count - 2)
-#define NTOK 5
-#define MAXTOK 128
-#endif /* OSF1 */
-
- char *tok[MAXTOK];
- int count = 0;
- pstring line2;
-
- pstrcpy(line2,line);
-
-#ifdef OSF1
- {
- size_t length;
- length = strlen(line2);
- if (line2[length-3] == ':')
- return(False);
- }
-#endif /* OSF1 */
-
- /* FIXME: Use next_token rather than strtok! */
- tok[0] = strtok(line2," \t");
- count++;
-
- while (((tok[count] = strtok(NULL," \t")) != NULL) && (count < MAXTOK)) {
- count++;
- }
-
- /* we must get at least NTOK tokens */
- if (count < NTOK)
- return(False);
-
- /* the Job and Total columns must be integer */
- if (!isdigit((int)*tok[JOBTOK]) || !isdigit((int)*tok[TOTALTOK])) return(False);
-
- buf->job = atoi(tok[JOBTOK]);
- buf->size = atoi(tok[TOTALTOK]);
- buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[USERTOK],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[FILETOK],sizeof(buf->fs_file)-1);
-
- if ((FILETOK + 1) != TOTALTOK) {
- int i;
-
- for (i = (FILETOK + 1); i < TOTALTOK; i++) {
- /* FIXME: Using fstrcat rather than other means is a bit
- * inefficient; this might be a problem for enormous queues with
- * many fields. */
- fstrcat(buf->fs_file, " ");
- fstrcat(buf->fs_file, tok[i]);
- }
- /* Ensure null termination. */
- fstrterminate(buf->fs_file);
- }
-
-#ifdef PRIOTOK
- buf->priority = atoi(tok[PRIOTOK]);
-#else
- buf->priority = 1;
-#endif
- return(True);
-}
-
-/*
-<magnus@hum.auc.dk>
-LPRng_time modifies the current date by inserting the hour and minute from
-the lpq output. The lpq time looks like "23:15:07"
-
-<allan@umich.edu> June 30, 1998.
-Modified to work with the re-written parse_lpq_lprng routine.
-
-<J.P.M.v.Itegem@tue.nl> Dec 17,1999
-Modified to work with lprng 3.16
-With lprng 3.16 The lpq time looks like
- "23:15:07"
- "23:15:07.100"
- "1999-12-16-23:15:07"
- "1999-12-16-23:15:07.100"
-
-*/
-static time_t LPRng_time(char *time_string)
-{
- time_t jobtime;
- struct tm t;
-
- jobtime = time(NULL); /* default case: take current time */
- t = *localtime(&jobtime);
-
- if ( atoi(time_string) < 24 ){
- t.tm_hour = atoi(time_string);
- t.tm_min = atoi(time_string+3);
- t.tm_sec = atoi(time_string+6);
- } else {
- t.tm_year = atoi(time_string)-1900;
- t.tm_mon = atoi(time_string+5)-1;
- t.tm_mday = atoi(time_string+8);
- t.tm_hour = atoi(time_string+11);
- t.tm_min = atoi(time_string+14);
- t.tm_sec = atoi(time_string+17);
- }
- jobtime = mktime(&t);
-
- return jobtime;
-}
-
-
-/****************************************************************************
- parse a lprng lpq line
- <allan@umich.edu> June 30, 1998.
- Re-wrote this to handle file names with spaces, multiple file names on one
- lpq line, etc;
-****************************************************************************/
-static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
-{
-#define LPRNG_RANKTOK 0
-#define LPRNG_USERTOK 1
-#define LPRNG_PRIOTOK 2
-#define LPRNG_JOBTOK 3
-#define LPRNG_FILETOK 4
-#define LPRNG_TOTALTOK (num_tok - 2)
-#define LPRNG_TIMETOK (num_tok - 1)
-#define LPRNG_NTOK 7
-#define LPRNG_MAXTOK 128 /* PFMA just to keep us from running away. */
-
- fstring tokarr[LPRNG_MAXTOK];
- const char *cptr;
- char *ptr;
- int num_tok = 0;
-
- cptr = line;
- while(next_token( &cptr, tokarr[num_tok], " \t", sizeof(fstring)) && (num_tok < LPRNG_MAXTOK))
- num_tok++;
-
- /* We must get at least LPRNG_NTOK tokens. */
- if (num_tok < LPRNG_NTOK) {
- return(False);
- }
-
- if (!isdigit((int)*tokarr[LPRNG_JOBTOK]) || !isdigit((int)*tokarr[LPRNG_TOTALTOK])) {
- return(False);
- }
-
- buf->job = atoi(tokarr[LPRNG_JOBTOK]);
- buf->size = atoi(tokarr[LPRNG_TOTALTOK]);
-
- if (strequal(tokarr[LPRNG_RANKTOK],"active")) {
- buf->status = LPQ_PRINTING;
- } else if (strequal(tokarr[LPRNG_RANKTOK],"done")) {
- buf->status = LPQ_PRINTED;
- } else if (isdigit((int)*tokarr[LPRNG_RANKTOK])) {
- buf->status = LPQ_QUEUED;
- } else {
- buf->status = LPQ_PAUSED;
- }
-
- buf->priority = *tokarr[LPRNG_PRIOTOK] -'A';
-
- buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]);
-
- StrnCpy(buf->fs_user,tokarr[LPRNG_USERTOK],sizeof(buf->fs_user)-1);
-
- /* The '@hostname' prevents windows from displaying the printing icon
- * for the current user on the taskbar. Plop in a null.
- */
-
- if ((ptr = strchr_m(buf->fs_user,'@')) != NULL) {
- *ptr = '\0';
- }
-
- StrnCpy(buf->fs_file,tokarr[LPRNG_FILETOK],sizeof(buf->fs_file)-1);
-
- if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) {
- int i;
-
- for (i = (LPRNG_FILETOK + 1); i < LPRNG_TOTALTOK; i++) {
- /* FIXME: Using fstrcat rather than other means is a bit
- * inefficient; this might be a problem for enormous queues with
- * many fields. */
- fstrcat(buf->fs_file, " ");
- fstrcat(buf->fs_file, tokarr[i]);
- }
- /* Ensure null termination. */
- fstrterminate(buf->fs_file);
- }
-
- return(True);
-}
-
-
-
-/*******************************************************************
-parse lpq on an aix system
-
-Queue Dev Status Job Files User PP % Blks Cp Rnk
-------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
-lazer lazer READY
-lazer lazer RUNNING 537 6297doc.A kvintus@IE 0 10 2445 1 1
- QUEUED 538 C.ps root@IEDVB 124 1 2
- QUEUED 539 E.ps root@IEDVB 28 1 3
- QUEUED 540 L.ps root@IEDVB 172 1 4
- QUEUED 541 P.ps root@IEDVB 22 1 5
-********************************************************************/
-static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
-{
- fstring tok[11];
- int count=0;
- const char *cline = line;
-
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN",0);
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
-
- for (count=0;
- count<10 &&
- next_token(&cline,tok[count],NULL, sizeof(tok[count]));
- count++) ;
-
- /* we must get 6 tokens */
- if (count < 10)
- {
- if ((count == 7) && ((strcmp(tok[0],"QUEUED") == 0) || (strcmp(tok[0],"HELD") == 0)))
- {
- /* the 2nd and 5th columns must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4])) return(False);
- buf->size = atoi(tok[4]) * 1024;
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[2],' '))
- fstrcpy(tok[2],"STDIN");
-
- /* only take the last part of the filename */
- {
- fstring tmp;
- char *p = strrchr_m(tok[2],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[2],tmp);
- }
- }
-
-
- buf->job = atoi(tok[1]);
- buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[3],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[2],sizeof(buf->fs_file)-1);
- }
- else
- {
- DEBUG(6,("parse_lpq_aix count=%d\n", count));
- return(False);
- }
- }
- else
- {
- /* the 4th and 9th columns must be integer */
- if (!isdigit((int)*tok[3]) || !isdigit((int)*tok[8])) return(False);
- buf->size = atoi(tok[8]) * 1024;
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[4],' '))
- fstrcpy(tok[4],"STDIN");
-
- /* only take the last part of the filename */
- {
- fstring tmp;
- char *p = strrchr_m(tok[4],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[4],tmp);
- }
- }
-
-
- buf->job = atoi(tok[3]);
- buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[5],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[4],sizeof(buf->fs_file)-1);
- }
-
-
- return(True);
-}
-
-
-/****************************************************************************
-parse a lpq line
-here is an example of lpq output under hpux; note there's no space after -o !
-$> lpstat -oljplus
-ljplus-2153 user priority 0 Jan 19 08:14 on ljplus
- util.c 125697 bytes
- server.c 110712 bytes
-ljplus-2154 user priority 0 Jan 19 08:14 from client
- (standard input) 7551 bytes
-****************************************************************************/
-static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
-{
- /* must read two lines to process, therefore keep some values static */
- static BOOL header_line_ok=False, base_prio_reset=False;
- static fstring jobuser;
- static int jobid;
- static int jobprio;
- static time_t jobtime;
- static int jobstat=LPQ_QUEUED;
- /* to store minimum priority to print, lpstat command should be invoked
- with -p option first, to work */
- static int base_prio;
- int count;
- char htab = '\011';
- const char *cline = line;
- fstring tok[12];
-
- /* If a line begins with a horizontal TAB, it is a subline type */
-
- if (line[0] == htab) { /* subline */
- /* check if it contains the base priority */
- if (!strncmp(line,"\tfence priority : ",18)) {
- base_prio=atoi(&line[18]);
- DEBUG(4, ("fence priority set at %d\n", base_prio));
- }
- if (!header_line_ok) return (False); /* incorrect header line */
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN",0);
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
-
- for (count=0; count<2 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
- /* we must get 2 tokens */
- if (count < 2) return(False);
-
- /* the 2nd column must be integer */
- if (!isdigit((int)*tok[1])) return(False);
-
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[0],' '))
- fstrcpy(tok[0],"STDIN");
-
- buf->size = atoi(tok[1]);
- StrnCpy(buf->fs_file,tok[0],sizeof(buf->fs_file)-1);
-
- /* fill things from header line */
- buf->time = jobtime;
- buf->job = jobid;
- buf->status = jobstat;
- buf->priority = jobprio;
- StrnCpy(buf->fs_user,jobuser,sizeof(buf->fs_user)-1);
-
- return(True);
- }
- else { /* header line */
- header_line_ok=False; /* reset it */
- if (first) {
- if (!base_prio_reset) {
- base_prio=0; /* reset it */
- base_prio_reset=True;
- }
- }
- else if (base_prio) base_prio_reset=False;
-
- /* handle the dash in the job id */
- string_sub(line,"-"," ",0);
-
- for (count=0; count<12 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
-
- /* we must get 8 tokens */
- if (count < 8) return(False);
-
- /* first token must be printer name (cannot check ?) */
- /* the 2nd, 5th & 7th column must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) return(False);
- jobid = atoi(tok[1]);
- StrnCpy(jobuser,tok[2],sizeof(buf->fs_user)-1);
- jobprio = atoi(tok[4]);
-
- /* process time */
- jobtime=EntryTime(tok, 5, count, 8);
- if (jobprio < base_prio) {
- jobstat = LPQ_PAUSED;
- DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n", jobid, jobprio, base_prio, jobstat));
- }
- else {
- jobstat = LPQ_QUEUED;
- if ((count >8) && (((strequal(tok[8],"on")) ||
- ((strequal(tok[8],"from")) &&
- ((count > 10)&&(strequal(tok[10],"on")))))))
- jobstat = LPQ_PRINTING;
- }
-
- header_line_ok=True; /* information is correct */
- return(False); /* need subline info to include into queuelist */
- }
-}
-
-
-/****************************************************************************
-parse a lpstat line
-
-here is an example of "lpstat -o dcslw" output under sysv
-
-dcslw-896 tridge 4712 Dec 20 10:30:30 on dcslw
-dcslw-897 tridge 4712 Dec 20 10:30:30 being held
-
-****************************************************************************/
-static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
-{
- fstring tok[9];
- int count=0;
- char *p;
- const char *cline = line;
-
- /*
- * Handle the dash in the job id, but make sure that we skip over
- * the printer name in case we have a dash in that.
- * Patch from Dom.Mitchell@palmerharvey.co.uk.
- */
-
- /*
- * Move to the first space.
- */
- for (p = line ; !isspace(*p) && *p; p++)
- ;
-
- /*
- * Back up until the last '-' character or
- * start of line.
- */
- for (; (p >= line) && (*p != '-'); p--)
- ;
-
- if((p >= line) && (*p == '-'))
- *p = ' ';
-
- for (count=0; count<9 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++)
- ;
-
- /* we must get 7 tokens */
- if (count < 7)
- return(False);
-
- /* the 2nd and 4th, 6th columns must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3]))
- return(False);
- if (!isdigit((int)*tok[5]))
- return(False);
-
- /* if the user contains a ! then trim the first part of it */
- if ((p=strchr_m(tok[2],'!'))) {
- fstring tmp;
- fstrcpy(tmp,p+1);
- fstrcpy(tok[2],tmp);
- }
-
- buf->job = atoi(tok[1]);
- buf->size = atoi(tok[3]);
- if (count > 7 && strequal(tok[7],"on"))
- buf->status = LPQ_PRINTING;
- else if (count > 8 && strequal(tok[7],"being") && strequal(tok[8],"held"))
- buf->status = LPQ_PAUSED;
- else
- buf->status = LPQ_QUEUED;
- buf->priority = 0;
- buf->time = EntryTime(tok, 4, count, 7);
- StrnCpy(buf->fs_user,tok[2],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[2],sizeof(buf->fs_file)-1);
- return(True);
-}
-
-/****************************************************************************
-parse a lpq line
-
-here is an example of lpq output under qnx
-Spooler: /qnx/spooler, on node 1
-Printer: txt (ready)
-0000: root [job #1 ] active 1146 bytes /etc/profile
-0001: root [job #2 ] ready 2378 bytes /etc/install
-0002: root [job #3 ] ready 1146 bytes -- standard input --
-****************************************************************************/
-static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
-{
- fstring tok[7];
- int count=0;
- const char *cline;
-
- DEBUG(4,("antes [%s]\n", line));
-
- /* handle the case of "-- standard input --" as a filename */
- string_sub(line,"standard input","STDIN",0);
- DEBUG(4,("despues [%s]\n", line));
- all_string_sub(line,"-- ","\"",0);
- all_string_sub(line," --","\"",0);
- DEBUG(4,("despues 1 [%s]\n", line));
-
- string_sub(line,"[job #","",0);
- string_sub(line,"]","",0);
- DEBUG(4,("despues 2 [%s]\n", line));
-
- for (count=0; count<7 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
-
- /* we must get 7 tokens */
- if (count < 7)
- return(False);
-
- /* the 3rd and 5th columns must be integer */
- if (!isdigit((int)*tok[2]) || !isdigit((int)*tok[4])) return(False);
-
- /* only take the last part of the filename */
- {
- fstring tmp;
- char *p = strrchr_m(tok[6],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[6],tmp);
- }
- }
-
-
- buf->job = atoi(tok[2]);
- buf->size = atoi(tok[4]);
- buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[1],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[6],sizeof(buf->fs_file)-1);
- return(True);
-}
-
-
-/****************************************************************************
- parse a lpq line for the plp printing system
- Bertrand Wallrich <Bertrand.Wallrich@loria.fr>
-
-redone by tridge. Here is a sample queue:
-
-Local Printer 'lp2' (fjall):
- Printing (started at Jun 15 13:33:58, attempt 1).
- Rank Owner Pr Opt Job Host Files Size Date
- active tridge X - 6 fjall /etc/hosts 739 Jun 15 13:33
- 3rd tridge X - 7 fjall /etc/hosts 739 Jun 15 13:33
-
-****************************************************************************/
-static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
-{
- fstring tok[11];
- int count=0;
- const char *cline = line;
-
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"stdin","STDIN",0);
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
-
- for (count=0; count<11 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
-
- /* we must get 11 tokens */
- if (count < 11)
- return(False);
-
- /* the first must be "active" or begin with an integer */
- if (strcmp(tok[0],"active") && !isdigit((int)tok[0][0]))
- return(False);
-
- /* the 5th and 8th must be integer */
- if (!isdigit((int)*tok[4]) || !isdigit((int)*tok[7]))
- return(False);
-
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[6],' '))
- fstrcpy(tok[6],"STDIN");
-
- /* only take the last part of the filename */
- {
- fstring tmp;
- char *p = strrchr_m(tok[6],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[6],tmp);
- }
- }
-
-
- buf->job = atoi(tok[4]);
-
- buf->size = atoi(tok[7]);
- if (strchr_m(tok[7],'K'))
- buf->size *= 1024;
- if (strchr_m(tok[7],'M'))
- buf->size *= 1024*1024;
-
- buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[1],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[6],sizeof(buf->fs_file)-1);
- return(True);
-}
-
-/****************************************************************************
-parse a qstat line
-
-here is an example of "qstat -l -d qms" output under softq
-
-Queue qms: 2 jobs; daemon active (313); enabled; accepting;
- job-ID submission-time pri size owner title
-205980: H 98/03/09 13:04:05 0 15733 stephenf chap1.ps
-206086:> 98/03/12 17:24:40 0 659 chris -
-206087: 98/03/12 17:24:45 0 4876 chris -
-Total: 21268 bytes in queue
-
-
-****************************************************************************/
-static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first)
-{
- fstring tok[10];
- int count=0;
- const char *cline = line;
-
- /* mung all the ":"s to spaces*/
- string_sub(line,":"," ",0);
-
- for (count=0; count<10 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
-
- /* we must get 9 tokens */
- if (count < 9)
- return(False);
-
- /* the 1st and 7th columns must be integer */
- if (!isdigit((int)*tok[0]) || !isdigit((int)*tok[6])) return(False);
- /* if the 2nd column is either '>' or 'H' then the 7th and 8th must be
- * integer, else it's the 6th and 7th that must be
- */
- if (*tok[1] == 'H' || *tok[1] == '>')
- {
- if (!isdigit((int)*tok[7]))
- return(False);
- buf->status = *tok[1] == '>' ? LPQ_PRINTING : LPQ_PAUSED;
- count = 1;
- }
- else
- {
- if (!isdigit((int)*tok[5]))
- return(False);
- buf->status = LPQ_QUEUED;
- count = 0;
- }
-
-
- buf->job = atoi(tok[0]);
- buf->size = atoi(tok[count+6]);
- buf->priority = atoi(tok[count+5]);
- StrnCpy(buf->fs_user,tok[count+7],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[count+8],sizeof(buf->fs_file)-1);
- buf->time = time(NULL); /* default case: take current time */
- {
- time_t jobtime;
- struct tm *t;
-
- t = localtime(&buf->time);
- t->tm_mday = atoi(tok[count+2]+6);
- t->tm_mon = atoi(tok[count+2]+3);
- switch (*tok[count+2])
- {
- case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]); break;
- default: t->tm_year = atoi(tok[count+2]); break;
- }
-
- t->tm_hour = atoi(tok[count+3]);
- t->tm_min = atoi(tok[count+4]);
- t->tm_sec = atoi(tok[count+5]);
- jobtime = mktime(t);
- if (jobtime != (time_t)-1)
- buf->time = jobtime;
- }
-
- return(True);
-}
-
-/*******************************************************************
-parse lpq on an NT system
-
- Windows 2000 LPD Server
- Printer \\10.0.0.2\NP17PCL (Paused)
-
-Owner Status Jobname Job-Id Size Pages Priority
-----------------------------------------------------------------------------
-root (9.99. Printing /usr/lib/rhs/rhs-pr 3 625 0 1
-root (9.99. Paused /usr/lib/rhs/rhs-pr 4 625 0 1
-jmcd Waiting Re: Samba Open Sour 26 32476 1 1
-
-********************************************************************/
-static BOOL parse_lpq_nt(char *line,print_queue_struct *buf,BOOL first)
-{
-#define LPRNT_OWNSIZ 11
-#define LPRNT_STATSIZ 9
-#define LPRNT_JOBSIZ 19
-#define LPRNT_IDSIZ 6
-#define LPRNT_SIZSIZ 9
- typedef struct
- {
- char owner[LPRNT_OWNSIZ];
- char space1;
- char status[LPRNT_STATSIZ];
- char space2;
- char jobname[LPRNT_JOBSIZ];
- char space3;
- char jobid[LPRNT_IDSIZ];
- char space4;
- char size[LPRNT_SIZSIZ];
- char terminator;
- } nt_lpq_line;
-
- nt_lpq_line parse_line;
-#define LPRNT_PRINTING "Printing"
-#define LPRNT_WAITING "Waiting"
-#define LPRNT_PAUSED "Paused"
-
- memset(&parse_line, '\0', sizeof(parse_line));
- strncpy((char *) &parse_line, line, sizeof(parse_line) -1);
-
- if (strlen((char *) &parse_line) != sizeof(parse_line) - 1)
- return(False);
-
- /* Just want the first word in the owner field - the username */
- if (strchr_m(parse_line.owner, ' '))
- *(strchr_m(parse_line.owner, ' ')) = '\0';
- else
- parse_line.space1 = '\0';
-
- /* Make sure we have an owner */
- if (!strlen(parse_line.owner))
- return(False);
-
- /* Make sure the status is valid */
- parse_line.space2 = '\0';
- trim_string(parse_line.status, NULL, " ");
- if (!strequal(parse_line.status, LPRNT_PRINTING) &&
- !strequal(parse_line.status, LPRNT_PAUSED) &&
- !strequal(parse_line.status, LPRNT_WAITING))
- return(False);
-
- parse_line.space3 = '\0';
- trim_string(parse_line.jobname, NULL, " ");
-
- buf->job = atoi(parse_line.jobid);
- buf->priority = 0;
- buf->size = atoi(parse_line.size);
- buf->time = time(NULL);
- StrnCpy(buf->fs_user, parse_line.owner, sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file, parse_line.jobname, sizeof(buf->fs_file)-1);
- if (strequal(parse_line.status, LPRNT_PRINTING))
- buf->status = LPQ_PRINTING;
- else if (strequal(parse_line.status, LPRNT_PAUSED))
- buf->status = LPQ_PAUSED;
- else
- buf->status = LPQ_QUEUED;
-
- return(True);
-}
-
-/*******************************************************************
-parse lpq on an OS2 system
-
-JobID File Name Rank Size Status Comment
------ --------------- ------ -------- ------------ ------------
- 3 Control 1 68 Queued root@psflinu
- 4 /etc/motd 2 11666 Queued root@psflinu
-
-********************************************************************/
-static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first)
-{
-#define LPROS2_IDSIZ 5
-#define LPROS2_JOBSIZ 15
-#define LPROS2_SIZSIZ 8
-#define LPROS2_STATSIZ 12
-#define LPROS2_OWNSIZ 12
- typedef struct
- {
- char jobid[LPROS2_IDSIZ];
- char space1[2];
- char jobname[LPROS2_JOBSIZ];
- char space2[14];
- char size[LPROS2_SIZSIZ];
- char space3[4];
- char status[LPROS2_STATSIZ];
- char space4[4];
- char owner[LPROS2_OWNSIZ];
- char terminator;
- } os2_lpq_line;
-
- os2_lpq_line parse_line;
-#define LPROS2_PRINTING "Printing"
-#define LPROS2_WAITING "Queued"
-#define LPROS2_PAUSED "Paused"
-
- memset(&parse_line, '\0', sizeof(parse_line));
- strncpy((char *) &parse_line, line, sizeof(parse_line) -1);
-
- if (strlen((char *) &parse_line) != sizeof(parse_line) - 1)
- return(False);
-
- /* Get the jobid */
- buf->job = atoi(parse_line.jobid);
-
- /* Get the job name */
- parse_line.space2[0] = '\0';
- trim_string(parse_line.jobname, NULL, " ");
- StrnCpy(buf->fs_file, parse_line.jobname, sizeof(buf->fs_file)-1);
-
- buf->priority = 0;
- buf->size = atoi(parse_line.size);
- buf->time = time(NULL);
-
- /* Make sure we have an owner */
- if (!strlen(parse_line.owner))
- return(False);
-
- /* Make sure we have a valid status */
- parse_line.space4[0] = '\0';
- trim_string(parse_line.status, NULL, " ");
- if (!strequal(parse_line.status, LPROS2_PRINTING) &&
- !strequal(parse_line.status, LPROS2_PAUSED) &&
- !strequal(parse_line.status, LPROS2_WAITING))
- return(False);
-
- StrnCpy(buf->fs_user, parse_line.owner, sizeof(buf->fs_user)-1);
- if (strequal(parse_line.status, LPROS2_PRINTING))
- buf->status = LPQ_PRINTING;
- else if (strequal(parse_line.status, LPROS2_PAUSED))
- buf->status = LPQ_PAUSED;
- else
- buf->status = LPQ_QUEUED;
-
- return(True);
-}
-
-static const char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL };
-static const char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL };
-static const char *stat2_strings[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL };
-
-#ifdef DEVELOPER
-
-/****************************************************************************
-parse a vlp line
-****************************************************************************/
-static BOOL parse_lpq_vlp(char *line,print_queue_struct *buf,BOOL first)
-{
- int toknum = 0;
- fstring tok;
- const char *cline = line;
-
- /* First line is printer status */
-
- if (!isdigit(line[0])) return False;
-
- /* Parse a print job entry */
-
- while(next_token(&cline, tok, NULL, sizeof(fstring))) {
- switch (toknum) {
- case 0:
- buf->job = atoi(tok);
- break;
- case 1:
- buf->size = atoi(tok);
- break;
- case 2:
- buf->status = atoi(tok);
- break;
- case 3:
- buf->time = atoi(tok);
- break;
- case 4:
- fstrcpy(buf->fs_user, tok);
- break;
- case 5:
- fstrcpy(buf->fs_file, tok);
- break;
- }
- toknum++;
- }
-
- return True;
-}
-
-#endif /* DEVELOPER */
-
-/****************************************************************************
-parse a lpq line. Choose printing style
-****************************************************************************/
-
-BOOL parse_lpq_entry(int snum,char *line,
- print_queue_struct *buf,
- print_status_struct *status,BOOL first)
-{
- BOOL ret;
-
- switch (lp_printing(snum))
- {
- case PRINT_SYSV:
- ret = parse_lpq_sysv(line,buf,first);
- break;
- case PRINT_AIX:
- ret = parse_lpq_aix(line,buf,first);
- break;
- case PRINT_HPUX:
- ret = parse_lpq_hpux(line,buf,first);
- break;
- case PRINT_QNX:
- ret = parse_lpq_qnx(line,buf,first);
- break;
- case PRINT_LPRNG:
- ret = parse_lpq_lprng(line,buf,first);
- break;
- case PRINT_PLP:
- ret = parse_lpq_plp(line,buf,first);
- break;
- case PRINT_SOFTQ:
- ret = parse_lpq_softq(line,buf,first);
- break;
- case PRINT_LPRNT:
- ret = parse_lpq_nt(line,buf,first);
- break;
- case PRINT_LPROS2:
- ret = parse_lpq_os2(line,buf,first);
- break;
-#ifdef DEVELOPER
- case PRINT_VLP:
- case PRINT_TEST:
- ret = parse_lpq_vlp(line,buf,first);
- break;
-#endif /* DEVELOPER */
- default:
- ret = parse_lpq_bsd(line,buf,first);
- break;
- }
-
- /* We don't want the newline in the status message. */
- {
- char *p = strchr_m(line,'\n');
- if (p) *p = 0;
- }
-
- /* in the LPRNG case, we skip lines starting by a space.*/
- if (line && !ret && (lp_printing(snum)==PRINT_LPRNG) )
- {
- if (line[0]==' ')
- return ret;
- }
-
-
- if (status && !ret)
- {
- /* a few simple checks to see if the line might be a
- printer status line:
- handle them so that most severe condition is shown */
- int i;
- strlower(line);
-
- switch (status->status) {
- case LPSTAT_OK:
- for (i=0; stat0_strings[i]; i++)
- if (strstr(line,stat0_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_OK;
- return ret;
- }
- case LPSTAT_STOPPED:
- for (i=0; stat1_strings[i]; i++)
- if (strstr(line,stat1_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_STOPPED;
- return ret;
- }
- case LPSTAT_ERROR:
- for (i=0; stat2_strings[i]; i++)
- if (strstr(line,stat2_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_ERROR;
- return ret;
- }
- break;
- }
- }
-
- return(ret);
-}
diff --git a/source4/printing/notify.c b/source4/printing/notify.c
deleted file mode 100644
index a745e9e308..0000000000
--- a/source4/printing/notify.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 2.2
- printing backend routines
- Copyright (C) Tim Potter, 2002
- Copyright (C) Gerald Carter, 2002
-
- 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 "printing.h"
-
-static TALLOC_CTX *send_ctx;
-
-static BOOL create_send_ctx(void)
-{
- if (!send_ctx)
- send_ctx = talloc_init("print notify queue");
-
- if (!send_ctx)
- return False;
-
- return True;
-}
-
-/****************************************************************************
- Turn a queue name into a snum.
-****************************************************************************/
-
-int print_queue_snum(const char *qname)
-{
- int snum = lp_servicenumber(qname);
- if (snum == -1 || !lp_print_ok(snum))
- return -1;
- return snum;
-}
-
-/*******************************************************************
- Used to decide if we need a short select timeout.
-*******************************************************************/
-
-BOOL print_notify_messages_pending(void)
-{
- return (notify_queue_head != NULL);
-}
-
-/*******************************************************************
- Flatten data into a message.
-*******************************************************************/
-
-static BOOL flatten_message(struct notify_queue *q)
-{
- struct spoolss_notify_msg *msg = q->msg;
- char *buf = NULL;
- size_t buflen = 0, len;
-
-again:
- len = 0;
-
- /* Pack header */
-
- len += tdb_pack(buf + len, buflen - len, "f", msg->printer);
-
- len += tdb_pack(buf + len, buflen - len, "ddddd",
- msg->type, msg->field, msg->id, msg->len, msg->flags);
-
- /* Pack data */
-
- if (msg->len == 0)
- len += tdb_pack(buf + len, buflen - len, "dd",
- msg->notify.value[0], msg->notify.value[1]);
- else
- len += tdb_pack(buf + len, buflen - len, "B",
- msg->len, msg->notify.data);
-
- if (buflen != len) {
- buf = talloc_realloc(send_ctx, buf, len);
- if (!buf)
- return False;
- buflen = len;
- goto again;
- }
-
- q->buf = buf;
- q->buflen = buflen;
-
- return True;
-}
-
-/*******************************************************************
- Send the batched messages - on a per-printer basis.
-*******************************************************************/
-
-static void print_notify_send_messages_to_printer(const char *printer, unsigned int timeout)
-{
- char *buf;
- struct notify_queue *pq, *pq_next;
- size_t msg_count = 0, offset = 0;
- size_t num_pids = 0;
- size_t i;
- pid_t *pid_list = NULL;
-
- /* Count the space needed to send the messages. */
- for (pq = notify_queue_head; pq; pq = pq->next) {
- if (strequal(printer, pq->msg->printer)) {
- if (!flatten_message(pq)) {
- DEBUG(0,("print_notify_send_messages: Out of memory\n"));
- talloc_destroy_pool(send_ctx);
- return;
- }
- offset += (pq->buflen + 4);
- msg_count++;
- }
- }
- offset += 4; /* For count. */
-
- buf = talloc(send_ctx, offset);
- if (!buf) {
- DEBUG(0,("print_notify_send_messages: Out of memory\n"));
- talloc_destroy_pool(send_ctx);
- return;
- }
-
- offset = 0;
- SIVAL(buf,offset,msg_count);
- offset += 4;
- for (pq = notify_queue_head; pq; pq = pq_next) {
- pq_next = pq->next;
-
- if (strequal(printer, pq->msg->printer)) {
- SIVAL(buf,offset,pq->buflen);
- offset += 4;
- memcpy(buf + offset, pq->buf, pq->buflen);
- offset += pq->buflen;
-
- /* Remove from list. */
- DLIST_REMOVE(notify_queue_head, pq);
- }
- }
-
- DEBUG(5, ("print_notify_send_messages_to_printer: sending %d print notify message%s to printer %s\n",
- msg_count, msg_count != 1 ? "s" : "", printer));
-
- /*
- * Get the list of PID's to send to.
- */
-
- if (!print_notify_pid_list(printer, send_ctx, &num_pids, &pid_list))
- return;
-
- for (i = 0; i < num_pids; i++)
- message_send_pid_with_timeout(pid_list[i], MSG_PRINTER_NOTIFY2, buf, offset, True, timeout);
-}
-
-/*******************************************************************
- Actually send the batched messages.
-*******************************************************************/
-
-void print_notify_send_messages(unsigned int timeout)
-{
- if (!print_notify_messages_pending())
- return;
-
- if (!create_send_ctx())
- return;
-
- while (print_notify_messages_pending())
- print_notify_send_messages_to_printer(notify_queue_head->msg->printer, timeout);
-
- talloc_destroy_pool(send_ctx);
-}
-
-/**********************************************************************
- deep copy a SPOOLSS_NOTIFY_MSG structure using a TALLOC_CTX
- *********************************************************************/
-
-static BOOL copy_notify2_msg( SPOOLSS_NOTIFY_MSG *to, SPOOLSS_NOTIFY_MSG *from )
-{
-
- if ( !to || !from )
- return False;
-
- memcpy( to, from, sizeof(SPOOLSS_NOTIFY_MSG) );
-
- if ( from->len ) {
- to->notify.data = talloc_memdup(send_ctx, from->notify.data, from->len );
- if ( !to->notify.data ) {
- DEBUG(0,("copy_notify2_msg: talloc_memdup() of size [%d] failed!\n", from->len ));
- return False;
- }
- }
-
-
- return True;
-}
-
-/*******************************************************************
- Batch up print notify messages.
-*******************************************************************/
-
-static void send_spoolss_notify2_msg(SPOOLSS_NOTIFY_MSG *msg)
-{
- struct notify_queue *pnqueue;
-
- /*
- * Ensure we only have one message unique to each name/type/field/id/flags
- * tuple. There is no point in sending multiple messages that match
- * as they will just cause flickering updates in the client.
- */
-
- for (tmp_ptr = notify_queue_head; tmp_ptr; tmp_ptr = tmp_ptr->next) {
- if (tmp_ptr->msg->type == msg->type &&
- tmp_ptr->msg->field == msg->field &&
- tmp_ptr->msg->id == msg->id &&
- tmp_ptr->msg->flags == msg->flags &&
- strequal(tmp_ptr->msg->printer, msg->printer)) {
-
- DEBUG(5, ("send_spoolss_notify2_msg: replacing message 0x%02x/0x%02x for printer %s \
-in notify_queue\n", msg->type, msg->field, msg->printer));
-
- tmp_ptr->msg = msg;
- return;
- }
- }
-
- /* Store the message on the pending queue. */
-
- pnqueue = talloc(send_ctx, sizeof(*pnqueue));
- if (!pnqueue) {
- DEBUG(0,("send_spoolss_notify2_msg: Out of memory.\n"));
- return;
- }
-
- /* allocate a new msg structure and copy the fields */
-
- if ( !(pnqueue->msg = (SPOOLSS_NOTIFY_MSG*)talloc(send_ctx, sizeof(SPOOLSS_NOTIFY_MSG))) ) {
- DEBUG(0,("send_spoolss_notify2_msg: talloc() of size [%d] failed!\n",
- sizeof(SPOOLSS_NOTIFY_MSG)));
- return;
- }
- copy_notify2_msg(pnqueue->msg, msg);
- pnqueue->buf = NULL;
- pnqueue->buflen = 0;
-
- DEBUG(5, ("send_spoolss_notify2_msg: appending message 0x%02x/0x%02x for printer %s \
-to notify_queue_head\n", msg->type, msg->field, msg->printer));
-
- /*
- * Note we add to the end of the list to ensure
- * the messages are sent in the order they were received. JRA.
- */
-
- DLIST_ADD_END(notify_queue_head, pnqueue, struct notify_queue *);
-}
-
-static void send_notify_field_values(const char *printer_name, uint32 type,
- uint32 field, uint32 id, uint32 value1,
- uint32 value2, uint32 flags)
-{
- struct spoolss_notify_msg *msg;
-
- if (lp_disable_spoolss())
- return;
-
- if (!create_send_ctx())
- return;
-
- msg = (struct spoolss_notify_msg *)talloc(send_ctx, sizeof(struct spoolss_notify_msg));
- if (!msg)
- return;
-
- ZERO_STRUCTP(msg);
-
- fstrcpy(msg->printer, printer_name);
- msg->type = type;
- msg->field = field;
- msg->id = id;
- msg->notify.value[0] = value1;
- msg->notify.value[1] = value2;
- msg->flags = flags;
-
- send_spoolss_notify2_msg(msg);
-}
-
-static void send_notify_field_buffer(const char *printer_name, uint32 type,
- uint32 field, uint32 id, uint32 len,
- char *buffer)
-{
- struct spoolss_notify_msg *msg;
-
- if (lp_disable_spoolss())
- return;
-
- if (!create_send_ctx())
- return;
-
- msg = (struct spoolss_notify_msg *)talloc(send_ctx, sizeof(struct spoolss_notify_msg));
- if (!msg)
- return;
-
- ZERO_STRUCTP(msg);
-
- fstrcpy(msg->printer, printer_name);
- msg->type = type;
- msg->field = field;
- msg->id = id;
- msg->len = len;
- msg->notify.data = buffer;
-
- send_spoolss_notify2_msg(msg);
-}
-
-/* Send a message that the printer status has changed */
-
-void notify_printer_status_byname(const char *printer_name, uint32 status)
-{
- /* Printer status stored in value1 */
-
- send_notify_field_values(printer_name, PRINTER_NOTIFY_TYPE,
- PRINTER_NOTIFY_STATUS, 0,
- status, 0, 0);
-}
-
-void notify_printer_status(int snum, uint32 status)
-{
- const char *printer_name = SERVICE(snum);
-
- if (printer_name)
- notify_printer_status_byname(printer_name, status);
-}
-
-void notify_job_status_byname(const char *printer_name, uint32 jobid, uint32 status,
- uint32 flags)
-{
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_STATUS, jobid,
- status, 0, flags);
-}
-
-void notify_job_status(int snum, uint32 jobid, uint32 status)
-{
- const char *printer_name = SERVICE(snum);
-
- notify_job_status_byname(printer_name, jobid, status, 0);
-}
-
-void notify_job_total_bytes(int snum, uint32 jobid, uint32 size)
-{
- const char *printer_name = SERVICE(snum);
-
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_TOTAL_BYTES, jobid,
- size, 0, 0);
-}
-
-void notify_job_total_pages(int snum, uint32 jobid, uint32 pages)
-{
- const char *printer_name = SERVICE(snum);
-
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_TOTAL_PAGES, jobid,
- pages, 0, 0);
-}
-
-void notify_job_username(int snum, uint32 jobid, char *name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME,
- jobid, strlen(name) + 1, name);
-}
-
-void notify_job_name(int snum, uint32 jobid, char *name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT,
- jobid, strlen(name) + 1, name);
-}
-
-void notify_job_submitted(int snum, uint32 jobid, time_t submitted)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED,
- jobid, sizeof(submitted), (char *)&submitted);
-}
-
-void notify_printer_driver(int snum, char *driver_name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME,
- snum, strlen(driver_name) + 1, driver_name);
-}
-
-void notify_printer_comment(int snum, char *comment)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT,
- snum, strlen(comment) + 1, comment);
-}
-
-void notify_printer_sharename(int snum, char *share_name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,
- snum, strlen(share_name) + 1, share_name);
-}
-
-void notify_printer_port(int snum, char *port_name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME,
- snum, strlen(port_name) + 1, port_name);
-}
-
-void notify_printer_location(int snum, char *location)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,
- snum, strlen(location) + 1, location);
-}
-
-void notify_printer_byname( char *printername, uint32 change, char *value )
-{
- int snum = print_queue_snum(printername);
- int type = PRINTER_NOTIFY_TYPE;
-
- if ( snum == -1 )
- return;
-
- send_notify_field_buffer( printername, type, change, snum, strlen(value)+1, value );
-}
-
-
-/****************************************************************************
- Return a malloced list of pid_t's that are interested in getting update
- messages on this print queue. Used in printing/notify to send the messages.
-****************************************************************************/
-
-BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list)
-{
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- TDB_DATA data;
- BOOL ret = True;
- size_t i, num_pids, offset;
- pid_t *pid_list;
-
- *p_num_pids = 0;
- *pp_pid_list = NULL;
-
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
-
- if (tdb_read_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n",
- printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- if (!data.dptr) {
- ret = True;
- goto done;
- }
-
- num_pids = data.dsize / 8;
-
- if ((pid_list = (pid_t *)talloc(mem_ctx, sizeof(pid_t) * num_pids)) == NULL) {
- ret = False;
- goto done;
- }
-
- for( i = 0, offset = 0; offset < data.dsize; offset += 8, i++)
- pid_list[i] = (pid_t)IVAL(data.dptr, offset);
-
- *pp_pid_list = pid_list;
- *p_num_pids = num_pids;
-
- ret = True;
-
- done:
-
- tdb_read_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
diff --git a/source4/printing/pcap.c b/source4/printing/pcap.c
deleted file mode 100644
index c399c3c6cc..0000000000
--- a/source4/printing/pcap.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- printcap parsing
- Copyright (C) Karl Auer 1993-1998
-
- Re-working by Martin Kiff, 1994
-
- Re-written again by Andrew Tridgell
-
- Modified for SVID support by Norm Jacobs, 1997
-
- Modified for CUPS support by Michael Sweet, 1999
-
- 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.
-*/
-
-/*
- * Parse printcap file.
- *
- * This module does exactly one thing - it looks into the printcap file
- * and tells callers if a specified string appears as a printer name.
- *
- * The way this module looks at the printcap file is very simplistic.
- * Only the local printcap file is inspected (no searching of NIS
- * databases etc).
- *
- * There are assumed to be one or more printer names per record, held
- * as a set of sub-fields separated by vertical bar symbols ('|') in the
- * first field of the record. The field separator is assumed to be a colon
- * ':' and the record separator a newline.
- *
- * Lines ending with a backspace '\' are assumed to flag that the following
- * line is a continuation line so that a set of lines can be read as one
- * printcap entry.
- *
- * A line stating with a hash '#' is assumed to be a comment and is ignored
- * Comments are discarded before the record is strung together from the
- * set of continuation lines.
- *
- * Opening a pipe for "lpc status" and reading that would probably
- * be pretty effective. Code to do this already exists in the freely
- * distributable PCNFS server code.
- *
- * Modified to call SVID/XPG4 support if printcap name is set to "lpstat"
- * in smb.conf under Solaris.
- *
- * Modified to call CUPS support if printcap name is set to "cups"
- * in smb.conf.
- */
-
-#include "includes.h"
-
-#ifdef AIX
-/* ******************************************
- Extend for AIX system and qconfig file
- from 'boulard@univ-rennes1.fr
- ****************************************** */
-static int strlocate(char *xpLine,char *xpS)
-{
- int iS,iL,iRet;
- char *p;
- iS = strlen(xpS);
- iL = strlen(xpLine);
-
- iRet = 0;
- p = xpLine;
- while (iL >= iS)
- {
- if (strncmp(p,xpS,iS) == 0) {iRet =1;break;};
- p++;
- iL--;
- }
- /*DEBUG(3,(" strlocate %s in line '%s',ret=%d\n",xpS,xpLine,iRet));*/
-
- return(iRet);
-}
-
-
-/* ******************************************************************* */
-/* * Scan qconfig and search all virtual printer (device printer) * */
-/* ******************************************************************* */
-static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
-{
- int iEtat;
- XFILE *pfile;
- char *line,*p;
- pstring name,comment;
- line = NULL;
- *name = 0;
- *comment = 0;
-
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- return;
- }
-
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '*' || *line == 0)
- continue;
- switch (iEtat)
- {
- case 0: /* locate an entry */
- if (*line == '\t' || *line == ' ') continue;
- if ((p=strchr_m(line,':')))
- {
- *p = '\0';
- p = strtok(line,":");
- if (strcmp(p,"bsh")!=0)
- {
- pstrcpy(name,p);
- iEtat = 1;
- continue;
- }
- }
- break;
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0) continue;
- if (*line != '\t' && *line != ' ')
- {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- fn(name,comment);
- iEtat = 0;
- continue;
- }
-
- if (strlocate(line,"backend"))
- {
- /* it's a device, not a virtual printer*/
- iEtat = 0;
- }
- else if (strlocate(line,"device"))
- {
- /* it's a good virtual printer */
- fn(name,comment);
- iEtat = 0;
- continue;
- }
- break;
- }
- }
- x_fclose(pfile);
-}
-
-/* Scan qconfig file and locate de printername */
-
-static BOOL ScanQconfig(char *psz,char *pszPrintername)
-{
- int iLg,iEtat;
- XFILE *pfile;
- char *pName;
- char *line;
-
- pName = NULL;
- line = NULL;
- if ((pszPrintername!= NULL) && ((iLg = strlen(pszPrintername)) > 0))
- pName = malloc(iLg+10);
- if (pName == NULL)
- {
- DEBUG(0,(" Unable to allocate memory for printer %s\n",pszPrintername));
- return(False);
- }
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- SAFE_FREE(pName);
- return(False);
- }
- slprintf(pName, iLg + 9, "%s:",pszPrintername);
- iLg = strlen(pName);
- /*DEBUG(3,( " Looking for entry %s\n",pName));*/
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '*' || *line == 0)
- continue;
- switch (iEtat)
- {
- case 0: /* scanning entry */
- if (strncmp(line,pName,iLg) == 0)
- {
- iEtat = 1;
- continue;
- }
- break;
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0) continue;
- if (*line != '\t' && *line != ' ')
- {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- free (line);
- SAFE_FREE(pName);
- fclose(pfile);
- return(True);
- }
-
- if (strlocate(line,"backend"))
- {
- /* it's a device, not a virtual printer*/
- iEtat = 0;
- }
- else if (strlocate(line,"device"))
- {
- /* it's a good virtual printer */
- free (line);
- SAFE_FREE(pName);
- fclose(pfile);
- return(True);
- }
- break;
- }
- }
- free (pName);
- x_fclose(pfile);
- return(False);
-}
-#endif /* AIX */
-
-
-/***************************************************************************
-Scan printcap file pszPrintcapname for a printer called pszPrintername.
-Return True if found, else False. Returns False on error, too, after logging
-the error at level 0. For generality, the printcap name may be passed - if
-passed as NULL, the configuration will be queried for the name.
-***************************************************************************/
-BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname)
-{
- char *line=NULL;
- const char *psz;
- char *p,*q;
- XFILE *pfile;
-
- if (pszPrintername == NULL || pszPrintername[0] == '\0')
- {
- DEBUG(0,( "Attempt to locate null printername! Internal error?\n"));
- return(False);
- }
-
- /* only go looking if no printcap name supplied */
- if ((psz = pszPrintcapname) == NULL || psz[0] == '\0')
- if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
- {
- DEBUG(0,( "No printcap file name configured!\n"));
- return(False);
- }
-
-#ifdef HAVE_CUPS
- if (strequal(psz, "cups"))
- return (cups_printername_ok(pszPrintername));
-#endif /* HAVE_CUPS */
-
-#ifdef SYSV
- if (strequal(psz, "lpstat"))
- return (sysv_printername_ok(pszPrintername));
-#endif
-
-#ifdef AIX
- if (strlocate(psz,"/qconfig"))
- return(ScanQconfig(psz,pszPrintername));
-#endif
-
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
- return(False);
- }
-
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '#' || *line == 0)
- continue;
-
- /* now we have a real printer line - cut it off at the first : */
- p = strchr_m(line,':');
- if (p) *p = 0;
-
- /* now just check if the name is in the list */
- /* NOTE: I avoid strtok as the fn calling this one may be using it */
- for (p=line; p; p=q)
- {
- if ((q = strchr_m(p,'|'))) *q++ = 0;
-
- if (strequal(p,pszPrintername))
- {
- SAFE_FREE(line);
- x_fclose(pfile);
- return(True);
- }
- p = q;
- }
- }
-
- x_fclose(pfile);
- return(False);
-}
-
-
-/***************************************************************************
-run a function on each printer name in the printcap file. The function is
-passed the primary name and the comment (if possible). Note the fn() takes
-strings in DOS codepage. This means the xxx_printer_fn() calls must be fixed
-to return DOS codepage. FIXME !! JRA.
-***************************************************************************/
-void pcap_printer_fn(void (*fn)(char *, char *))
-{
- pstring name,comment;
- char *line;
- char *psz;
- char *p,*q;
- XFILE *pfile;
-
- /* only go looking if no printcap name supplied */
- if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
- {
- DEBUG(0,( "No printcap file name configured!\n"));
- return;
- }
-
-#ifdef HAVE_CUPS
- if (strequal(psz, "cups")) {
- cups_printer_fn(fn);
- return;
- }
-#endif /* HAVE_CUPS */
-
-#ifdef SYSV
- if (strequal(psz, "lpstat")) {
- sysv_printer_fn(fn);
- return;
- }
-#endif
-
-#ifdef AIX
- if (strlocate(psz,"/qconfig"))
- {
- ScanQconfig_fn(psz,fn);
- return;
- }
-#endif
-
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
- return;
- }
-
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '#' || *line == 0)
- continue;
-
- /* now we have a real printer line - cut it off at the first : */
- p = strchr_m(line,':');
- if (p) *p = 0;
-
- /* now find the most likely printer name and comment
- this is pure guesswork, but it's better than nothing */
- *name = 0;
- *comment = 0;
- for (p=line; p; p=q)
- {
- BOOL has_punctuation;
- if ((q = strchr_m(p,'|'))) *q++ = 0;
-
- has_punctuation = (strchr_m(p,' ') || strchr_m(p,'\t') || strchr_m(p,'(') || strchr_m(p,')'));
-
- if (strlen(p)>strlen(comment) && has_punctuation)
- {
- StrnCpy(comment,p,sizeof(comment)-1);
- continue;
- }
-
- if (strlen(p) <= MAXPRINTERLEN && strlen(p)>strlen(name) && !has_punctuation)
- {
- if (!*comment) pstrcpy(comment,name);
- pstrcpy(name,p);
- continue;
- }
-
- if (!strchr_m(comment,' ') &&
- strlen(p) > strlen(comment))
- {
- StrnCpy(comment,p,sizeof(comment)-1);
- continue;
- }
- }
-
- comment[60] = 0;
- name[MAXPRINTERLEN] = 0;
-
- if (*name)
- fn(name,comment);
- }
- x_fclose(pfile);
-}
diff --git a/source4/printing/print_cups.c b/source4/printing/print_cups.c
deleted file mode 100644
index 7cf21c966e..0000000000
--- a/source4/printing/print_cups.c
+++ /dev/null
@@ -1,1293 +0,0 @@
-/*
- * Support code for the Common UNIX Printing System ("CUPS")
- *
- * Copyright 1999-2003 by Michael R Sweet.
- *
- * 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 "printing.h"
-
-#ifdef HAVE_CUPS
-#include <cups/cups.h>
-#include <cups/language.h>
-
-
-/*
- * CUPS printing interface definitions...
- */
-
-static int cups_job_delete(int snum, struct printjob *pjob);
-static int cups_job_pause(int snum, struct printjob *pjob);
-static int cups_job_resume(int snum, struct printjob *pjob);
-static int cups_job_submit(int snum, struct printjob *pjob);
-static int cups_queue_get(int snum, print_queue_struct **q,
- print_status_struct *status);
-static int cups_queue_pause(int snum);
-static int cups_queue_resume(int snum);
-
-
-struct printif cups_printif =
- {
- cups_queue_get,
- cups_queue_pause,
- cups_queue_resume,
- cups_job_delete,
- cups_job_pause,
- cups_job_resume,
- cups_job_submit,
- };
-
-/*
- * 'cups_passwd_cb()' - The CUPS password callback...
- */
-
-static const char * /* O - Password or NULL */
-cups_passwd_cb(const char *prompt) /* I - Prompt */
-{
- /*
- * Always return NULL to indicate that no password is available...
- */
-
- return (NULL);
-}
-
-
-/*
- * 'cups_printer_fn()' - Call a function for every printer known to the
- * system.
- */
-
-void cups_printer_fn(void (*fn)(char *, char *))
-{
- /* I - Function to call */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language; /* Default language */
- char *name, /* printer-name attribute */
- *make_model, /* printer-make-and-model attribute */
- *info; /* printer-info attribute */
- static const char *requested[] =/* Requested attributes */
- {
- "printer-name",
- "printer-make-and-model",
- "printer-info"
- };
-
-
- DEBUG(5,("cups_printer_fn(%p)\n", fn));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return;
- }
-
- /*
- * Build a CUPS_GET_PRINTERS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- */
-
- request = ippNew();
-
- request->request.op.operation_id = CUPS_GET_PRINTERS;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(requested) / sizeof(requested[0])),
- NULL, requested);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(0,("Unable to get printer list - %s\n",
- ippErrorString(cupsLastError())));
- httpClose(http);
- return;
- }
-
- for (attr = response->attrs; attr != NULL;)
- {
- /*
- * Skip leading attributes until we hit a printer...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Pull the needed attributes from this printer...
- */
-
- name = NULL;
- make_model = NULL;
- info = NULL;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
- {
- if (strcmp(attr->name, "printer-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME)
- name = attr->values[0].string.text;
-
- if (strcmp(attr->name, "printer-make-and-model") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- make_model = attr->values[0].string.text;
-
- if (strcmp(attr->name, "printer-info") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- info = attr->values[0].string.text;
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (name == NULL)
- break;
-
- if (info == NULL || !info[0])
- (*fn)(name, make_model);
- else
- (*fn)(name, info);
-
-
- }
-
- ippDelete(response);
-
-
- /*
- * Build a CUPS_GET_CLASSES request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- */
-
- request = ippNew();
-
- request->request.op.operation_id = CUPS_GET_CLASSES;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(requested) / sizeof(requested[0])),
- NULL, requested);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(0,("Unable to get printer list - %s\n",
- ippErrorString(cupsLastError())));
- httpClose(http);
- return;
- }
-
- for (attr = response->attrs; attr != NULL;)
- {
- /*
- * Skip leading attributes until we hit a printer...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Pull the needed attributes from this printer...
- */
-
- name = NULL;
- make_model = NULL;
- info = NULL;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
- {
- if (strcmp(attr->name, "printer-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME)
- name = attr->values[0].string.text;
-
- if (strcmp(attr->name, "printer-make-and-model") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- make_model = attr->values[0].string.text;
-
- if (strcmp(attr->name, "printer-info") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- info = attr->values[0].string.text;
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (name == NULL)
- break;
-
- if (info == NULL || !info[0])
- (*fn)(name, make_model);
- else
- (*fn)(name, info);
-
-
- }
-
- ippDelete(response);
-
- /*
- * Close the connection to the server...
- */
-
- httpClose(http);
-}
-
-
-/*
- * 'cups_printername_ok()' - Provide the equivalent of pcap_printername_ok()
- * for CUPS.
- * O - 1 if printer name OK
- * I - Name of printer
- */
-int cups_printername_ok(const char *name)
-{
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_printername_ok(\"%s\")\n", name));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(3,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (0);
- }
-
- /*
- * Build an IPP_GET_PRINTER_ATTRS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes", NULL, "printer-uri");
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", name);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(3,("Unable to get printer status for %s - %s\n", name,
- ippErrorString(cupsLastError())));
- httpClose(http);
- return (0);
- }
-
- httpClose(http);
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- {
- DEBUG(3,("Unable to get printer status for %s - %s\n", name,
- ippErrorString(response->request.status.status_code)));
- ippDelete(response);
- return (0);
- }
- else
- {
- ippDelete(response);
- return (1);
- }
-}
-
-
-/*
- * 'cups_job_delete()' - Delete a job.
- */
-
-static int
-cups_job_delete(int snum, struct printjob *pjob)
-{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_job_delete(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_CANCEL_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * job-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_CANCEL_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- /*
- * Do the request and get back a response...
- */
-
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- return (ret);
-}
-
-
-/*
- * 'cups_job_pause()' - Pause a job.
- */
-
-static int
-cups_job_pause(int snum, struct printjob *pjob)
-{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_HOLD_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * job-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_HOLD_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- /*
- * Do the request and get back a response...
- */
-
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- return (ret);
-}
-
-
-/*
- * 'cups_job_resume()' - Resume a paused job.
- */
-
-static int
-cups_job_resume(int snum, struct printjob *pjob)
-{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_RELEASE_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * job-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_RELEASE_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- /*
- * Do the request and get back a response...
- */
-
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- return (ret);
-}
-
-
-/*
- * 'cups_job_submit()' - Submit a job for printing.
- */
-
-static int
-cups_job_submit(int snum, struct printjob *pjob)
-{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_PRINT_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- * [document-data]
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_PRINT_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- PRINTERNAME(snum));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "job-originating-host-name", NULL,
- get_remote_machine_name());
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
- pjob->jobname);
-
- /*
- * Do the request and get back a response...
- */
-
- slprintf(uri, sizeof(uri) - 1, "/printers/%s", PRINTERNAME(snum));
-
- ret = 1;
- if ((response = cupsDoFileRequest(http, request, uri,
- pjob->filename)) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- if ( ret == 0 )
- unlink(pjob->filename);
- /* else print_job_end will do it for us */
-
- return (ret);
-}
-
-
-/*
- * 'cups_queue_get()' - Get all the jobs in the print queue.
- */
-
-static int
-cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
-{
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- int qcount, /* Number of active queue entries */
- qalloc; /* Number of queue entries allocated */
- print_queue_struct *queue, /* Queue entries */
- *temp; /* Temporary pointer for queue */
- const char *user_name, /* job-originating-user-name attribute */
- *job_name; /* job-name attribute */
- int job_id; /* job-id attribute */
- int job_k_octets; /* job-k-octets attribute */
- time_t job_time; /* time-at-creation attribute */
- ipp_jstate_t job_status; /* job-status attribute */
- int job_priority; /* job-priority attribute */
- static const char *jattrs[] = /* Requested job attributes */
- {
- "job-id",
- "job-k-octets",
- "job-name",
- "job-originating-user-name",
- "job-priority",
- "job-state",
- "time-at-creation",
- };
- static const char *pattrs[] = /* Requested printer attributes */
- {
- "printer-state",
- "printer-state-message"
- };
-
-
- DEBUG(5,("cups_queue_get(%d, %p, %p)\n", snum, q, status));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (0);
- }
-
- /*
- * Generate the printer URI...
- */
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- PRINTERNAME(snum));
-
- /*
- * Build an IPP_GET_JOBS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_JOBS;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(jattrs) / sizeof(jattrs[0])),
- NULL, jattrs);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
- ippErrorString(cupsLastError())));
- httpClose(http);
- return (0);
- }
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- {
- DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
- ippErrorString(response->request.status.status_code)));
- ippDelete(response);
- httpClose(http);
-
- return (0);
- }
-
- /*
- * Process the jobs...
- */
-
- qcount = 0;
- qalloc = 0;
- queue = NULL;
-
- for (attr = response->attrs; attr != NULL; attr = attr->next)
- {
- /*
- * Skip leading attributes until we hit a job...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Allocate memory as needed...
- */
- if (qcount >= qalloc)
- {
- qalloc += 16;
-
- temp = Realloc(queue, sizeof(print_queue_struct) * qalloc);
-
- if (temp == NULL)
- {
- DEBUG(0,("cups_queue_get: Not enough memory!"));
- ippDelete(response);
- httpClose(http);
-
- SAFE_FREE(queue);
- return (0);
- }
-
- queue = temp;
- }
-
- temp = queue + qcount;
- memset(temp, 0, sizeof(print_queue_struct));
-
- /*
- * Pull the needed attributes from this job...
- */
-
- job_id = 0;
- job_priority = 50;
- job_status = IPP_JOB_PENDING;
- job_time = 0;
- job_k_octets = 0;
- user_name = NULL;
- job_name = NULL;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
- {
- if (attr->name == NULL)
- {
- attr = attr->next;
- break;
- }
-
- if (strcmp(attr->name, "job-id") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_id = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-k-octets") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_k_octets = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-priority") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_priority = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-state") == 0 &&
- attr->value_tag == IPP_TAG_ENUM)
- job_status = (ipp_jstate_t)(attr->values[0].integer);
-
- if (strcmp(attr->name, "time-at-creation") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_time = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME)
- job_name = attr->values[0].string.text;
-
- if (strcmp(attr->name, "job-originating-user-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME)
- user_name = attr->values[0].string.text;
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (user_name == NULL || job_name == NULL || job_id == 0)
- {
- if (attr == NULL)
- break;
- else
- continue;
- }
-
- temp->job = job_id;
- temp->size = job_k_octets * 1024;
- temp->status = job_status == IPP_JOB_PENDING ? LPQ_QUEUED :
- job_status == IPP_JOB_STOPPED ? LPQ_PAUSED :
- job_status == IPP_JOB_HELD ? LPQ_PAUSED :
- LPQ_PRINTING;
- temp->priority = job_priority;
- temp->time = job_time;
- strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1);
- strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1);
-
- qcount ++;
-
- if (attr == NULL)
- break;
- }
-
- ippDelete(response);
-
- /*
- * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
- * following attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(pattrs) / sizeof(pattrs[0])),
- NULL, pattrs);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(0,("Unable to get printer status for %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- httpClose(http);
- *q = queue;
- return (qcount);
- }
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- {
- DEBUG(0,("Unable to get printer status for %s - %s\n", PRINTERNAME(snum),
- ippErrorString(response->request.status.status_code)));
- ippDelete(response);
- httpClose(http);
- *q = queue;
- return (qcount);
- }
-
- /*
- * Get the current printer status and convert it to the SAMBA values.
- */
-
- if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
- {
- if (attr->values[0].integer == IPP_PRINTER_STOPPED)
- status->status = LPSTAT_STOPPED;
- else
- status->status = LPSTAT_OK;
- }
-
- if ((attr = ippFindAttribute(response, "printer-state-message",
- IPP_TAG_TEXT)) != NULL)
- fstrcpy(status->message, attr->values[0].string.text);
-
- ippDelete(response);
-
- /*
- * Return the job queue...
- */
-
- httpClose(http);
-
- *q = queue;
- return (qcount);
-}
-
-
-/*
- * 'cups_queue_pause()' - Pause a print queue.
- */
-
-static int
-cups_queue_pause(int snum)
-{
- extern userdom_struct current_user_info;
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_queue_pause(%d)\n", snum));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_PAUSE_PRINTER request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_PAUSE_PRINTER;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- PRINTERNAME(snum));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, current_user_info.unix_name);
-
- /*
- * Do the request and get back a response...
- */
-
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- return (ret);
-}
-
-
-/*
- * 'cups_queue_resume()' - Restart a print queue.
- */
-
-static int
-cups_queue_resume(int snum)
-{
- extern userdom_struct current_user_info;
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_queue_resume(%d)\n", snum));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_RESUME_PRINTER request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_RESUME_PRINTER;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- PRINTERNAME(snum));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, current_user_info.unix_name);
-
- /*
- * Do the request and get back a response...
- */
-
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- return (ret);
-}
-
-
-#else
- /* this keeps fussy compilers happy */
- void print_cups_dummy(void) {}
-#endif /* HAVE_CUPS */
diff --git a/source4/printing/print_generic.c b/source4/printing/print_generic.c
deleted file mode 100644
index aae2844ded..0000000000
--- a/source4/printing/print_generic.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- printing command routines
- Copyright (C) Andrew Tridgell 1992-2000
-
- 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 "printing.h"
-
-
-/*
- * Generic printing interface definitions...
- */
-
-static int generic_job_delete(int snum, struct printjob *pjob);
-static int generic_job_pause(int snum, struct printjob *pjob);
-static int generic_job_resume(int snum, struct printjob *pjob);
-static int generic_job_submit(int snum, struct printjob *pjob);
-static int generic_queue_get(int snum, print_queue_struct **q,
- print_status_struct *status);
-static int generic_queue_pause(int snum);
-static int generic_queue_resume(int snum);
-
-
-struct printif generic_printif =
- {
- generic_queue_get,
- generic_queue_pause,
- generic_queue_resume,
- generic_job_delete,
- generic_job_pause,
- generic_job_resume,
- generic_job_submit,
- };
-
-/****************************************************************************
-run a given print command
-a null terminated list of value/substitute pairs is provided
-for local substitution strings
-****************************************************************************/
-static int print_run_command(int snum,char *command, int *outfd, ...)
-{
-
- pstring syscmd;
- char *arg;
- int ret;
- va_list ap;
- va_start(ap, outfd);
-
- if (!command || !*command) return -1;
-
- if (!VALID_SNUM(snum)) {
- DEBUG(0,("Invalid snum %d for command %s\n", snum, command));
- return -1;
- }
-
- pstrcpy(syscmd, command);
-
- while ((arg = va_arg(ap, char *))) {
- char *value = va_arg(ap,char *);
- pstring_sub(syscmd, arg, value);
- }
- va_end(ap);
-
- pstring_sub(syscmd, "%p", PRINTERNAME(snum));
- standard_sub_snum(snum,syscmd,sizeof(syscmd));
-
- ret = smbrun(syscmd,outfd);
-
- DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
-
- return ret;
-}
-
-
-/****************************************************************************
-delete a print job
-****************************************************************************/
-static int generic_job_delete(int snum, struct printjob *pjob)
-{
- fstring jobstr;
-
- /* need to delete the spooled entry */
- slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command(
- snum,
- lp_lprmcommand(snum), NULL,
- "%j", jobstr,
- "%T", timestring(pjob->starttime),
- NULL);
-}
-
-/****************************************************************************
-pause a job
-****************************************************************************/
-static int generic_job_pause(int snum, struct printjob *pjob)
-{
- fstring jobstr;
-
- /* need to pause the spooled entry */
- slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command(snum,
- lp_lppausecommand(snum), NULL,
- "%j", jobstr,
- NULL);
-}
-
-/****************************************************************************
-resume a job
-****************************************************************************/
-static int generic_job_resume(int snum, struct printjob *pjob)
-{
- fstring jobstr;
-
- /* need to pause the spooled entry */
- slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command(snum,
- lp_lpresumecommand(snum), NULL,
- "%j", jobstr,
- NULL);
-}
-
-/****************************************************************************
- Submit a file for printing - called from print_job_end()
-****************************************************************************/
-
-static int generic_job_submit(int snum, struct printjob *pjob)
-{
- int ret;
- pstring current_directory;
- pstring print_directory;
- char *wd, *p;
- pstring jobname;
- fstring job_page_count, job_size;
-
- /* we print from the directory path to give the best chance of
- parsing the lpq output */
- wd = sys_getwd(current_directory);
- if (!wd)
- return 0;
-
- pstrcpy(print_directory, pjob->filename);
- p = strrchr_m(print_directory,'/');
- if (!p)
- return 0;
- *p++ = 0;
-
- if (chdir(print_directory) != 0)
- return 0;
-
- pstrcpy(jobname, pjob->jobname);
- pstring_sub(jobname, "'", "_");
- slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
- slprintf(job_size, sizeof(job_size)-1, "%d", pjob->size);
-
- /* send it to the system spooler */
- ret = print_run_command(snum,
- lp_printcommand(snum), NULL,
- "%s", p,
- "%J", jobname,
- "%f", p,
- "%z", job_size,
- "%c", job_page_count,
- NULL);
-
- chdir(wd);
-
- return ret;
-}
-
-
-/****************************************************************************
-get the current list of queued jobs
-****************************************************************************/
-static int generic_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
-{
- char **qlines;
- int fd;
- int numlines, i, qcount;
- print_queue_struct *queue = NULL;
- fstring printer_name;
-
- fstrcpy(printer_name, lp_servicename(snum));
-
- print_run_command(snum, lp_lpqcommand(snum), &fd, NULL);
-
- if (fd == -1) {
- DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
- printer_name ));
- return 0;
- }
-
- numlines = 0;
- qlines = fd_lines_load(fd, &numlines);
- close(fd);
-
- /* turn the lpq output into a series of job structures */
- qcount = 0;
- ZERO_STRUCTP(status);
- if (numlines)
- queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(numlines+1));
-
- if (queue) {
- for (i=0; i<numlines; i++) {
- /* parse the line */
- if (parse_lpq_entry(snum,qlines[i],
- &queue[qcount],status,qcount==0)) {
- qcount++;
- }
- }
- }
- file_lines_free(qlines);
-
- *q = queue;
- return qcount;
-}
-
-/****************************************************************************
- pause a queue
-****************************************************************************/
-static int generic_queue_pause(int snum)
-{
- return print_run_command(snum, lp_queuepausecommand(snum), NULL, NULL);
-}
-
-/****************************************************************************
- resume a queue
-****************************************************************************/
-static int generic_queue_resume(int snum)
-{
- return print_run_command(snum, lp_queueresumecommand(snum), NULL, NULL);
-}
diff --git a/source4/printing/print_svid.c b/source4/printing/print_svid.c
deleted file mode 100644
index 07b157bcd9..0000000000
--- a/source4/printing/print_svid.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 1997-1998 by Norm Jacobs, Colorado Springs, Colorado, USA
- * Copyright (C) 1997-1998 by Sun Microsystem, Inc.
- * All Rights Reserved
- *
- * 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.
- */
-
-/*
- * This module implements support for gathering and comparing available
- * printer information on a SVID or XPG4 compliant system. It does this
- * through the use of the SVID/XPG4 command "lpstat(1)".
- *
- * The expectations is that execution of the command "lpstat -v" will
- * generate responses in the form of:
- *
- * device for serial: /dev/term/b
- * system for fax: server
- * system for color: server (as printer chroma)
- */
-
-
-#include "includes.h"
-
-#ifdef SYSV
-
-typedef struct printer {
- char *name;
- struct printer *next;
-} printer_t;
-static printer_t *printers = NULL;
-
-static void populate_printers(void)
-{
- char **lines;
- int i;
-
- lines = file_lines_pload("/usr/bin/lpstat -v", NULL);
- if (!lines) return;
-
- for (i=0;lines[i];i++) {
- printer_t *ptmp;
- char *name, *tmp;
- char *buf = lines[i];
-
- /* eat "system/device for " */
- if (((tmp = strchr_m(buf, ' ')) == NULL) ||
- ((tmp = strchr_m(++tmp, ' ')) == NULL))
- continue;
-
- /*
- * In case we're only at the "for ".
- */
-
- if(!strncmp("for ",++tmp,4)) {
- tmp=strchr_m(tmp, ' ');
- tmp++;
- }
-
- /* Eat whitespace. */
-
- while(*tmp == ' ')
- ++tmp;
-
- /*
- * On HPUX there is an extra line that can be ignored.
- * d.thibadeau 2001/08/09
- */
- if(!strncmp("remote to",tmp,9))
- continue;
-
- name = tmp;
-
- /* truncate the ": ..." */
- if ((tmp = strchr_m(name, ':')) != NULL)
- *tmp = '\0';
-
- /* add it to the cache */
- if ((ptmp = malloc(sizeof (*ptmp))) != NULL) {
- ZERO_STRUCTP(ptmp);
- if((ptmp->name = strdup(name)) == NULL)
- DEBUG(0,("populate_printers: malloc fail in strdup !\n"));
- ptmp->next = printers;
- printers = ptmp;
- } else {
- DEBUG(0,("populate_printers: malloc fail for ptmp\n"));
- }
- }
-
- file_lines_free(lines);
-}
-
-
-/*
- * provide the equivalent of pcap_printer_fn() for SVID/XPG4 conforming
- * systems. It was unclear why pcap_printer_fn() was tossing names longer
- * than 8 characters. I suspect that its a protocol limit, but amazingly
- * names longer than 8 characters appear to work with my test
- * clients (Win95/NT).
- */
-void sysv_printer_fn(void (*fn)(char *, char *))
-{
- printer_t *tmp;
-
- if (printers == NULL)
- populate_printers();
- for (tmp = printers; tmp != NULL; tmp = tmp->next)
- (fn)(tmp->name, "");
-}
-
-
-/*
- * provide the equivalent of pcap_printername_ok() for SVID/XPG4 conforming
- * systems.
- */
-int sysv_printername_ok(const char *name)
-{
- printer_t *tmp;
-
- if (printers == NULL)
- populate_printers();
- for (tmp = printers; tmp != NULL; tmp = tmp->next)
- if (strcmp(tmp->name, name) == 0)
- return (True);
- return (False);
-}
-
-#else
-/* this keeps fussy compilers happy */
- void print_svid_dummy(void);
- void print_svid_dummy(void) {}
-#endif
diff --git a/source4/printing/printfsp.c b/source4/printing/printfsp.c
deleted file mode 100644
index 5d230f8be4..0000000000
--- a/source4/printing/printfsp.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- printing backend routines for smbd - using files_struct rather
- than only snum
- Copyright (C) Andrew Tridgell 1992-2000
-
- 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"
-
-/***************************************************************************
-open a print file and setup a fsp for it. This is a wrapper around
-print_job_start().
-***************************************************************************/
-
-files_struct *print_fsp_open(struct tcon_context *conn, char *fname)
-{
- int jobid;
- SMB_STRUCT_STAT sbuf;
- extern struct current_user current_user;
- files_struct *fsp = file_new(conn);
- fstring name;
-
- if(!fsp)
- return NULL;
-
- fstrcpy( name, "Remote Downlevel Document");
- if (fname) {
- char *p = strrchr(fname, '/');
- fstrcat(name, " ");
- if (!p)
- p = fname;
- fstrcat(name, p);
- }
-
- jobid = print_job_start(&current_user, SNUM(conn), name, NULL);
- if (jobid == -1) {
- file_free(fsp);
- return NULL;
- }
-
- /* Convert to RAP id. */
- fsp->rap_print_jobid = pjobid_to_rap(SNUM(conn), jobid);
- if (fsp->rap_print_jobid == 0) {
- /* We need to delete the entry in the tdb. */
- pjob_delete(SNUM(conn), jobid);
- file_free(fsp);
- return NULL;
- }
-
- /* setup a full fsp */
- fsp->fd = print_job_fd(SNUM(conn),jobid);
- GetTimeOfDay(&fsp->open_time);
- fsp->vuid = current_user.vuid;
- fsp->size = 0;
- fsp->pos = -1;
- fsp->can_lock = True;
- fsp->can_read = False;
- fsp->can_write = True;
- fsp->share_mode = 0;
- fsp->print_file = True;
- fsp->modified = False;
- fsp->oplock_type = NO_OPLOCK;
- fsp->sent_oplock_break = NO_BREAK_SENT;
- fsp->is_directory = False;
- fsp->directory_delete_on_close = False;
- string_set(&fsp->fsp_name,print_job_fname(SNUM(conn),jobid));
- fsp->wbmpx_ptr = NULL;
- fsp->wcp = NULL;
- conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf);
- fsp->mode = sbuf.st_mode;
- fsp->inode = sbuf.st_ino;
- fsp->dev = sbuf.st_dev;
-
- conn->num_files_open++;
-
- return fsp;
-}
-
-/****************************************************************************
-print a file - called on closing the file
-****************************************************************************/
-void print_fsp_end(files_struct *fsp, BOOL normal_close)
-{
- uint32 jobid;
- int snum;
-
- if (fsp->share_mode == FILE_DELETE_ON_CLOSE) {
- /*
- * Truncate the job. print_job_end will take
- * care of deleting it for us. JRA.
- */
- sys_ftruncate(fsp->fd, 0);
- }
-
- if (fsp->fsp_name) {
- string_free(&fsp->fsp_name);
- }
-
- if (!rap_to_pjobid(fsp->rap_print_jobid, &snum, &jobid)) {
- DEBUG(3,("print_fsp_end: Unable to convert RAP jobid %u to print jobid.\n",
- (unsigned int)fsp->rap_print_jobid ));
- return;
- }
-
- print_job_end(SNUM(fsp->conn),jobid, normal_close);
-}
diff --git a/source4/printing/printing.c b/source4/printing/printing.c
deleted file mode 100644
index e4d9e5f785..0000000000
--- a/source4/printing/printing.c
+++ /dev/null
@@ -1,2128 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- printing backend routines
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Jeremy Allison 2002
-
- 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 "printing.h"
-
-/* Current printer interface */
-static struct printif *current_printif = &generic_printif;
-
-/*
- the printing backend revolves around a tdb database that stores the
- SMB view of the print queue
-
- The key for this database is a jobid - a internally generated number that
- uniquely identifies a print job
-
- reading the print queue involves two steps:
- - possibly running lpq and updating the internal database from that
- - reading entries from the database
-
- jobids are assigned when a job starts spooling.
-*/
-
-/***************************************************************************
- Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
- bit RPC jobids.... JRA.
-***************************************************************************/
-
-static TDB_CONTEXT *rap_tdb;
-static uint16 next_rap_jobid;
-
-uint16 pjobid_to_rap(int snum, uint32 jobid)
-{
- uint16 rap_jobid;
- TDB_DATA data, key;
- char jinfo[8];
-
- DEBUG(10,("pjobid_to_rap: called.\n"));
-
- if (!rap_tdb) {
- /* Create the in-memory tdb. */
- rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
- if (!rap_tdb)
- return 0;
- }
-
- SIVAL(&jinfo,0,(int32)snum);
- SIVAL(&jinfo,4,jobid);
-
- key.dptr = (char *)&jinfo;
- key.dsize = sizeof(jinfo);
- data = tdb_fetch(rap_tdb, key);
- if (data.dptr && data.dsize == sizeof(uint16)) {
- memcpy(&rap_jobid, data.dptr, sizeof(uint16));
- SAFE_FREE(data.dptr);
- DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
- (unsigned int)jobid,
- (unsigned int)rap_jobid));
- return rap_jobid;
- }
- SAFE_FREE(data.dptr);
- /* Not found - create and store mapping. */
- rap_jobid = ++next_rap_jobid;
- if (rap_jobid == 0)
- rap_jobid = ++next_rap_jobid;
- data.dptr = (char *)&rap_jobid;
- data.dsize = sizeof(rap_jobid);
- tdb_store(rap_tdb, key, data, TDB_REPLACE);
- tdb_store(rap_tdb, data, key, TDB_REPLACE);
-
- DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
- (unsigned int)jobid,
- (unsigned int)rap_jobid));
- return rap_jobid;
-}
-
-BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
-{
- TDB_DATA data, key;
-
- DEBUG(10,("rap_to_pjobid called.\n"));
-
- if (!rap_tdb)
- return False;
-
- key.dptr = (char *)&rap_jobid;
- key.dsize = sizeof(rap_jobid);
- data = tdb_fetch(rap_tdb, key);
- if (data.dptr && data.dsize == 8) {
- *psnum = IVAL(data.dptr,0);
- *pjobid = IVAL(data.dptr,4);
- DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
- (unsigned int)*pjobid,
- (unsigned int)rap_jobid));
- SAFE_FREE(data.dptr);
- return True;
- }
-
- DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
- (unsigned int)rap_jobid));
- SAFE_FREE(data.dptr);
- return False;
-}
-
-static void rap_jobid_delete(int snum, uint32 jobid)
-{
- TDB_DATA key, data;
- uint16 rap_jobid;
- char jinfo[8];
-
- DEBUG(10,("rap_jobid_delete: called.\n"));
-
- if (!rap_tdb)
- return;
-
- SIVAL(&jinfo,0,(int32)snum);
- SIVAL(&jinfo,4,jobid);
-
- key.dptr = (char *)&jinfo;
- key.dsize = sizeof(jinfo);
- data = tdb_fetch(rap_tdb, key);
- if (!data.dptr || (data.dsize != sizeof(uint16))) {
- DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
- (unsigned int)jobid ));
- SAFE_FREE(data.dptr);
- return;
- }
-
- DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
- (unsigned int)jobid ));
-
- memcpy(&rap_jobid, data.dptr, sizeof(uint16));
- SAFE_FREE(data.dptr);
- data.dptr = (char *)&rap_jobid;
- data.dsize = sizeof(rap_jobid);
- tdb_delete(rap_tdb, key);
- tdb_delete(rap_tdb, data);
-}
-
-static pid_t local_pid;
-
-static int get_queue_status(int, print_status_struct *);
-
-/****************************************************************************
- Initialise the printing backend. Called once at startup before the fork().
-****************************************************************************/
-
-BOOL print_backend_init(void)
-{
- const char *sversion = "INFO/version";
- pstring printing_path;
- int services = lp_numservices();
- int snum;
-
- if (local_pid == sys_getpid())
- return True;
-
- unlink(lock_path("printing.tdb"));
- pstrcpy(printing_path,lock_path("printing"));
- mkdir(printing_path,0755);
-
- local_pid = sys_getpid();
-
- /* handle a Samba upgrade */
-
- for (snum = 0; snum < services; snum++) {
- struct tdb_print_db *pdb;
- if (!lp_print_ok(snum))
- continue;
-
- pdb = get_print_db_byname(lp_const_servicename(snum));
- if (!pdb)
- continue;
- if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
- DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
- release_print_db(pdb);
- return False;
- }
- if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
- tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
- tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
- }
- tdb_unlock_bystring(pdb->tdb, sversion);
- release_print_db(pdb);
- }
-
- close_all_print_db(); /* Don't leave any open. */
-
- /* select the appropriate printing interface... */
-#ifdef HAVE_CUPS
- if (strcmp(lp_printcapname(), "cups") == 0)
- current_printif = &cups_printif;
-#endif /* HAVE_CUPS */
-
- /* do NT print initialization... */
- return nt_printing_init();
-}
-
-/****************************************************************************
- Shut down printing backend. Called once at shutdown to close the tdb.
-****************************************************************************/
-
-void printing_end(void)
-{
- close_all_print_db(); /* Don't leave any open. */
-}
-
-/****************************************************************************
- Useful function to generate a tdb key.
-****************************************************************************/
-
-static TDB_DATA print_key(uint32 jobid)
-{
- static uint32 j;
- TDB_DATA ret;
-
- j = jobid;
- ret.dptr = (void *)&j;
- ret.dsize = sizeof(j);
- return ret;
-}
-
-/***********************************************************************
- unpack a pjob from a tdb buffer
-***********************************************************************/
-
-int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
-{
- int len = 0;
- int used;
-
- if ( !buf || !pjob )
- return -1;
-
- len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
- &pjob->pid,
- &pjob->sysjob,
- &pjob->fd,
- &pjob->starttime,
- &pjob->status,
- &pjob->size,
- &pjob->page_count,
- &pjob->spooled,
- &pjob->smbjob,
- pjob->filename,
- pjob->jobname,
- pjob->user,
- pjob->queuename);
-
- if ( len == -1 )
- return -1;
-
- if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
- return -1;
-
- len += used;
-
- return len;
-
-}
-
-/****************************************************************************
- Useful function to find a print job in the database.
-****************************************************************************/
-
-static struct printjob *print_job_find(int snum, uint32 jobid)
-{
- static struct printjob pjob;
- TDB_DATA ret;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
-
-
- if (!pdb)
- return NULL;
-
- ret = tdb_fetch(pdb->tdb, print_key(jobid));
- release_print_db(pdb);
-
- if (!ret.dptr)
- return NULL;
-
- if ( pjob.nt_devmode )
- free_nt_devicemode( &pjob.nt_devmode );
-
- ZERO_STRUCT( pjob );
-
- if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
- SAFE_FREE(ret.dptr);
- return NULL;
- }
-
- SAFE_FREE(ret.dptr);
- return &pjob;
-}
-
-/* Convert a unix jobid to a smb jobid */
-
-static uint32 sysjob_to_jobid_value;
-
-static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
- TDB_DATA data, void *state)
-{
- struct printjob *pjob;
- int *sysjob = (int *)state;
-
- if (!data.dptr || data.dsize == 0)
- return 0;
-
- pjob = (struct printjob *)data.dptr;
- if (key.dsize != sizeof(uint32))
- return 0;
-
- if (*sysjob == pjob->sysjob) {
- uint32 *jobid = (uint32 *)key.dptr;
-
- sysjob_to_jobid_value = *jobid;
- return 1;
- }
-
- return 0;
-}
-
-/****************************************************************************
- This is a *horribly expensive call as we have to iterate through all the
- current printer tdb's. Don't do this often ! JRA.
-****************************************************************************/
-
-uint32 sysjob_to_jobid(int unix_jobid)
-{
- int services = lp_numservices();
- int snum;
-
- sysjob_to_jobid_value = (uint32)-1;
-
- for (snum = 0; snum < services; snum++) {
- struct tdb_print_db *pdb;
- if (!lp_print_ok(snum))
- continue;
- pdb = get_print_db_byname(lp_const_servicename(snum));
- if (pdb)
- tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
- release_print_db(pdb);
- if (sysjob_to_jobid_value != (uint32)-1)
- return sysjob_to_jobid_value;
- }
- return (uint32)-1;
-}
-
-/****************************************************************************
- Send notifications based on what has changed after a pjob_store.
-****************************************************************************/
-
-static struct {
- uint32 lpq_status;
- uint32 spoolss_status;
-} lpq_to_spoolss_status_map[] = {
- { LPQ_QUEUED, JOB_STATUS_QUEUED },
- { LPQ_PAUSED, JOB_STATUS_PAUSED },
- { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
- { LPQ_PRINTING, JOB_STATUS_PRINTING },
- { LPQ_DELETING, JOB_STATUS_DELETING },
- { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
- { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
- { LPQ_PRINTED, JOB_STATUS_PRINTED },
- { LPQ_DELETED, JOB_STATUS_DELETED },
- { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
- { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
- { -1, 0 }
-};
-
-/* Convert a lpq status value stored in printing.tdb into the
- appropriate win32 API constant. */
-
-static uint32 map_to_spoolss_status(uint32 lpq_status)
-{
- int i = 0;
-
- while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
- if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
- return lpq_to_spoolss_status_map[i].spoolss_status;
- i++;
- }
-
- return 0;
-}
-
-static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
- struct printjob *new_data)
-{
- BOOL new_job = False;
-
- if (!old_data)
- new_job = True;
-
- /* Notify the job name first */
-
- if (new_job || !strequal(old_data->jobname, new_data->jobname))
- notify_job_name(snum, jobid, new_data->jobname);
-
- /* Job attributes that can't be changed. We only send
- notification for these on a new job. */
-
- if (new_job) {
- notify_job_submitted(snum, jobid, new_data->starttime);
- notify_job_username(snum, jobid, new_data->user);
- }
-
- /* Job attributes of a new job or attributes that can be
- modified. */
-
- if (new_job || old_data->status != new_data->status)
- notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status));
-
- if (new_job || old_data->size != new_data->size)
- notify_job_total_bytes(snum, jobid, new_data->size);
-
- if (new_job || old_data->page_count != new_data->page_count)
- notify_job_total_pages(snum, jobid, new_data->page_count);
-}
-
-/****************************************************************************
- Store a job structure back to the database.
-****************************************************************************/
-
-static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
-{
- TDB_DATA old_data, new_data;
- BOOL ret = False;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
- char *buf = NULL;
- int len, newlen, buflen;
-
-
- if (!pdb)
- return False;
-
- /* Get old data */
-
- old_data = tdb_fetch(pdb->tdb, print_key(jobid));
-
- /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
-
- newlen = 0;
-
- do {
- len = 0;
- buflen = newlen;
- len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
- pjob->pid,
- pjob->sysjob,
- pjob->fd,
- pjob->starttime,
- pjob->status,
- pjob->size,
- pjob->page_count,
- pjob->spooled,
- pjob->smbjob,
- pjob->filename,
- pjob->jobname,
- pjob->user,
- pjob->queuename);
-
- len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
-
- if (buflen != len) {
- char *tb;
-
- tb = (char *)Realloc(buf, len);
- if (!tb) {
- DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
- goto done;
- }
- else
- buf = tb;
- newlen = len;
- }
- } while ( buflen != len );
-
-
- /* Store new data */
-
- new_data.dptr = buf;
- new_data.dsize = len;
- ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
-
- release_print_db(pdb);
-
- /* Send notify updates for what has changed */
-
- if ( ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob)) )
- pjob_store_notify( snum, jobid, (struct printjob *)old_data.dptr, pjob );
-
-done:
- SAFE_FREE( old_data.dptr );
- SAFE_FREE( buf );
-
- return ret;
-}
-
-/****************************************************************************
- Remove a job structure from the database.
-****************************************************************************/
-
-void pjob_delete(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- uint32 job_status = 0;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
-
- if (!pdb)
- return;
-
- if (!pjob) {
- DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n",
- (unsigned int)jobid));
- release_print_db(pdb);
- return;
- }
-
- /* Send a notification that a job has been deleted */
-
- job_status = map_to_spoolss_status(pjob->status);
-
- /* We must cycle through JOB_STATUS_DELETING and
- JOB_STATUS_DELETED for the port monitor to delete the job
- properly. */
-
- job_status |= JOB_STATUS_DELETING;
- notify_job_status(snum, jobid, job_status);
-
- job_status |= JOB_STATUS_DELETED;
- notify_job_status(snum, jobid, job_status);
-
- /* Remove from printing.tdb */
-
- tdb_delete(pdb->tdb, print_key(jobid));
- release_print_db(pdb);
- rap_jobid_delete(snum, jobid);
-}
-
-/****************************************************************************
- Parse a file name from the system spooler to generate a jobid.
-****************************************************************************/
-
-static uint32 print_parse_jobid(char *fname)
-{
- int jobid;
-
- if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
- return (uint32)-1;
- fname += strlen(PRINT_SPOOL_PREFIX);
-
- jobid = atoi(fname);
- if (jobid <= 0)
- return (uint32)-1;
-
- return (uint32)jobid;
-}
-
-/****************************************************************************
- List a unix job in the print database.
-****************************************************************************/
-
-static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
-{
- struct printjob pj, *old_pj;
-
- if (jobid == (uint32)-1)
- jobid = q->job + UNIX_JOB_START;
-
- /* Preserve the timestamp on an existing unix print job */
-
- old_pj = print_job_find(snum, jobid);
-
- ZERO_STRUCT(pj);
-
- pj.pid = (pid_t)-1;
- pj.sysjob = q->job;
- pj.fd = -1;
- pj.starttime = old_pj ? old_pj->starttime : q->time;
- pj.status = q->status;
- pj.size = q->size;
- pj.spooled = True;
- pj.smbjob = (old_pj != NULL ? True : False);
- fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
- if (jobid < UNIX_JOB_START)
- fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
- else
- fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
- fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
- fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum));
-
- pjob_store(snum, jobid, &pj);
-}
-
-
-struct traverse_struct {
- print_queue_struct *queue;
- int qcount, snum, maxcount, total_jobs;
- time_t lpq_time;
-};
-
-/****************************************************************************
- Utility fn to delete any jobs that are no longer active.
-****************************************************************************/
-
-static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct traverse_struct *ts = (struct traverse_struct *)state;
- struct printjob pjob;
- uint32 jobid;
- int i;
-
- if ( key.dsize != sizeof(jobid) )
- return 0;
-
- memcpy(&jobid, key.dptr, sizeof(jobid));
- if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
- return 0;
- free_nt_devicemode( &pjob.nt_devmode );
-
-
- if (ts->snum != lp_servicenumber(pjob.queuename)) {
- /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
- return 0;
- }
-
- if (!pjob.smbjob) {
- /* remove a unix job if it isn't in the system queue any more */
-
- for (i=0;i<ts->qcount;i++) {
- uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
- if (jobid == u_jobid)
- break;
- }
- if (i == ts->qcount)
- pjob_delete(ts->snum, jobid);
- else
- ts->total_jobs++;
- return 0;
- }
-
- /* maybe it hasn't been spooled yet */
- if (!pjob.spooled) {
- /* if a job is not spooled and the process doesn't
- exist then kill it. This cleans up after smbd
- deaths */
- if (!process_exists(pjob.pid))
- pjob_delete(ts->snum, jobid);
- else
- ts->total_jobs++;
- return 0;
- }
-
- for (i=0;i<ts->qcount;i++) {
- uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
- if (jobid == curr_jobid)
- break;
- }
-
- /* The job isn't in the system queue - we have to assume it has
- completed, so delete the database entry. */
-
- if (i == ts->qcount) {
-
- /* A race can occur between the time a job is spooled and
- when it appears in the lpq output. This happens when
- the job is added to printing.tdb when another smbd
- running print_queue_update() has completed a lpq and
- is currently traversing the printing tdb and deleting jobs.
- Don't delete the job if it was submitted after the lpq_time. */
-
- if (pjob.starttime < ts->lpq_time)
- pjob_delete(ts->snum, jobid);
- else
- ts->total_jobs++;
- }
- else
- ts->total_jobs++;
-
- return 0;
-}
-
-/****************************************************************************
- Check if the print queue has been updated recently enough.
-****************************************************************************/
-
-static void print_cache_flush(int snum)
-{
- fstring key;
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return;
- slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
- tdb_store_int32(pdb->tdb, key, -1);
- release_print_db(pdb);
-}
-
-/****************************************************************************
- Check if someone already thinks they are doing the update.
-****************************************************************************/
-
-static pid_t get_updating_pid(fstring printer_name)
-{
- fstring keystr;
- TDB_DATA data, key;
- pid_t updating_pid;
- struct tdb_print_db *pdb = get_print_db_byname(printer_name);
-
- if (!pdb)
- return (pid_t)-1;
- slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
-
- data = tdb_fetch(pdb->tdb, key);
- release_print_db(pdb);
- if (!data.dptr || data.dsize != sizeof(pid_t)) {
- SAFE_FREE(data.dptr);
- return (pid_t)-1;
- }
-
- memcpy(&updating_pid, data.dptr, sizeof(pid_t));
- SAFE_FREE(data.dptr);
-
- if (process_exists(updating_pid))
- return updating_pid;
-
- return (pid_t)-1;
-}
-
-/****************************************************************************
- Set the fact that we're doing the update, or have finished doing the update
- in the tdb.
-****************************************************************************/
-
-static void set_updating_pid(const fstring printer_name, BOOL delete)
-{
- fstring keystr;
- TDB_DATA key;
- TDB_DATA data;
- pid_t updating_pid = sys_getpid();
- struct tdb_print_db *pdb = get_print_db_byname(printer_name);
-
- if (!pdb)
- return;
-
- slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
-
- if (delete) {
- tdb_delete(pdb->tdb, key);
- release_print_db(pdb);
- return;
- }
-
- data.dptr = (void *)&updating_pid;
- data.dsize = sizeof(pid_t);
-
- tdb_store(pdb->tdb, key, data, TDB_REPLACE);
- release_print_db(pdb);
-}
-
-/****************************************************************************
- Update the internal database from the system print queue for a queue.
-****************************************************************************/
-
-static void print_queue_update(int snum)
-{
- int i, qcount;
- print_queue_struct *queue = NULL;
- print_status_struct status;
- print_status_struct old_status;
- struct printjob *pjob;
- struct traverse_struct tstruct;
- fstring keystr, printer_name, cachestr;
- TDB_DATA data, key;
- struct tdb_print_db *pdb;
-
- fstrcpy(printer_name, lp_const_servicename(snum));
- pdb = get_print_db_byname(printer_name);
- if (!pdb)
- return;
-
- /*
- * Check to see if someone else is doing this update.
- * This is essentially a mutex on the update.
- */
-
- if (get_updating_pid(printer_name) != -1) {
- release_print_db(pdb);
- return;
- }
-
- /* Lock the queue for the database update */
-
- slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
- /* Only wait 10 seconds for this. */
- if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
- DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
- release_print_db(pdb);
- return;
- }
-
- /*
- * Ensure that no one else got in here.
- * If the updating pid is still -1 then we are
- * the winner.
- */
-
- if (get_updating_pid(printer_name) != -1) {
- /*
- * Someone else is doing the update, exit.
- */
- tdb_unlock_bystring(pdb->tdb, keystr);
- release_print_db(pdb);
- return;
- }
-
- /*
- * We're going to do the update ourselves.
- */
-
- /* Tell others we're doing the update. */
- set_updating_pid(printer_name, False);
-
- /*
- * Allow others to enter and notice we're doing
- * the update.
- */
-
- tdb_unlock_bystring(pdb->tdb, keystr);
-
- /*
- * Update the cache time FIRST ! Stops others even
- * attempting to get the lock and doing this
- * if the lpq takes a long time.
- */
-
- slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
- tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
-
- /* get the current queue using the appropriate interface */
- ZERO_STRUCT(status);
-
- qcount = (*(current_printif->queue_get))(snum, &queue, &status);
-
- DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
- "s" : "", printer_name));
-
- /*
- any job in the internal database that is marked as spooled
- and doesn't exist in the system queue is considered finished
- and removed from the database
-
- any job in the system database but not in the internal database
- is added as a unix job
-
- fill in any system job numbers as we go
- */
- for (i=0; i<qcount; i++) {
- uint32 jobid = print_parse_jobid(queue[i].fs_file);
-
- if (jobid == (uint32)-1) {
- /* assume its a unix print job */
- print_unix_job(snum, &queue[i], jobid);
- continue;
- }
-
- /* we have an active SMB print job - update its status */
- pjob = print_job_find(snum, jobid);
- if (!pjob) {
- /* err, somethings wrong. Probably smbd was restarted
- with jobs in the queue. All we can do is treat them
- like unix jobs. Pity. */
- print_unix_job(snum, &queue[i], jobid);
- continue;
- }
-
- pjob->sysjob = queue[i].job;
- pjob->status = queue[i].status;
-
- pjob_store(snum, jobid, pjob);
- }
-
- /* now delete any queued entries that don't appear in the
- system queue */
- tstruct.queue = queue;
- tstruct.qcount = qcount;
- tstruct.snum = snum;
- tstruct.total_jobs = 0;
- tstruct.lpq_time = time(NULL);
-
- tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
-
- SAFE_FREE(tstruct.queue);
-
- DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
- printer_name, tstruct.total_jobs ));
-
- tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
-
- get_queue_status(snum, &old_status);
- if (old_status.qcount != qcount)
- DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
- old_status.qcount, qcount, printer_name ));
-
- /* store the new queue status structure */
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
-
- status.qcount = qcount;
- data.dptr = (void *)&status;
- data.dsize = sizeof(status);
- tdb_store(pdb->tdb, key, data, TDB_REPLACE);
-
- /*
- * Update the cache time again. We want to do this call
- * as little as possible...
- */
-
- slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
- tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
-
- /* Delete our pid from the db. */
- set_updating_pid(printer_name, True);
- release_print_db(pdb);
-}
-
-/****************************************************************************
- Create/Update an entry in the print tdb that will allow us to send notify
- updates only to interested smbd's.
-****************************************************************************/
-
-BOOL print_notify_register_pid(int snum)
-{
- TDB_DATA data;
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- const char *printername;
- uint32 mypid = (uint32)sys_getpid();
- BOOL ret = False;
- size_t i;
-
- /* if (snum == -1), then the change notify request was
- on a print server handle and we need to register on
- all print queus */
-
- if (snum == -1)
- {
- int num_services = lp_numservices();
- int idx;
-
- for ( idx=0; idx<num_services; idx++ ) {
- if (lp_snum_ok(idx) && lp_print_ok(idx) )
- print_notify_register_pid(idx);
- }
-
- return True;
- }
- else /* register for a specific printer */
- {
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
- }
-
- if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
- printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- /* Add ourselves and increase the refcount. */
-
- for (i = 0; i < data.dsize; i += 8) {
- if (IVAL(data.dptr,i) == mypid) {
- uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
- SIVAL(data.dptr, i+4, new_refcount);
- break;
- }
- }
-
- if (i == data.dsize) {
- /* We weren't in the list. Realloc. */
- data.dptr = Realloc(data.dptr, data.dsize + 8);
- if (!data.dptr) {
- DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
- printername));
- goto done;
- }
- data.dsize += 8;
- SIVAL(data.dptr,data.dsize - 8,mypid);
- SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
- }
-
- /* Store back the record. */
- if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to update pid \
-list for printer %s\n", printername));
- goto done;
- }
-
- ret = True;
-
- done:
-
- tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
-
-/****************************************************************************
- Update an entry in the print tdb that will allow us to send notify
- updates only to interested smbd's.
-****************************************************************************/
-
-BOOL print_notify_deregister_pid(int snum)
-{
- TDB_DATA data;
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- const char *printername;
- uint32 mypid = (uint32)sys_getpid();
- size_t i;
- BOOL ret = False;
-
- /* if ( snum == -1 ), we are deregister a print server handle
- which means to deregister on all print queues */
-
- if (snum == -1)
- {
- int num_services = lp_numservices();
- int idx;
-
- for ( idx=0; idx<num_services; idx++ ) {
- if ( lp_snum_ok(idx) && lp_print_ok(idx) )
- print_notify_deregister_pid(idx);
- }
-
- return True;
- }
- else /* deregister a specific printer */
- {
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
- }
-
- if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to lock \
-printer %s database\n", printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- /* Reduce refcount. Remove ourselves if zero. */
-
- for (i = 0; i < data.dsize; ) {
- if (IVAL(data.dptr,i) == mypid) {
- uint32 refcount = IVAL(data.dptr, i+4);
-
- refcount--;
-
- if (refcount == 0) {
- if (data.dsize - i > 8)
- memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
- data.dsize -= 8;
- continue;
- }
- SIVAL(data.dptr, i+4, refcount);
- }
-
- i += 8;
- }
-
- if (data.dsize == 0)
- SAFE_FREE(data.dptr);
-
- /* Store back the record. */
- if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to update pid \
-list for printer %s\n", printername));
- goto done;
- }
-
- ret = True;
-
- done:
-
- tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
-
-/****************************************************************************
- Check if a jobid is valid. It is valid if it exists in the database.
-****************************************************************************/
-
-BOOL print_job_exists(int snum, uint32 jobid)
-{
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
- BOOL ret;
-
- if (!pdb)
- return False;
- ret = tdb_exists(pdb->tdb, print_key(jobid));
- release_print_db(pdb);
- return ret;
-}
-
-/****************************************************************************
- Give the fd used for a jobid.
-****************************************************************************/
-
-int print_job_fd(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- if (!pjob)
- return -1;
- /* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != local_pid)
- return -1;
- return pjob->fd;
-}
-
-/****************************************************************************
- Give the filename used for a jobid.
- Only valid for the process doing the spooling and when the job
- has not been spooled.
-****************************************************************************/
-
-char *print_job_fname(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- if (!pjob || pjob->spooled || pjob->pid != local_pid)
- return NULL;
- return pjob->filename;
-}
-
-
-/****************************************************************************
- Give the filename used for a jobid.
- Only valid for the process doing the spooling and when the job
- has not been spooled.
-****************************************************************************/
-
-NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
-
- if ( !pjob )
- return NULL;
-
- return pjob->nt_devmode;
-}
-
-/****************************************************************************
- Set the place in the queue for a job.
-****************************************************************************/
-
-BOOL print_job_set_place(int snum, uint32 jobid, int place)
-{
- DEBUG(2,("print_job_set_place not implemented yet\n"));
- return False;
-}
-
-/****************************************************************************
- Set the name of a job. Only possible for owner.
-****************************************************************************/
-
-BOOL print_job_set_name(int snum, uint32 jobid, char *name)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- if (!pjob || pjob->pid != local_pid)
- return False;
-
- fstrcpy(pjob->jobname, name);
- return pjob_store(snum, jobid, pjob);
-}
-
-/****************************************************************************
- Delete a print job - don't update queue.
-****************************************************************************/
-
-static BOOL print_job_delete1(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- int result = 0;
-
- if (!pjob)
- return False;
-
- /*
- * If already deleting just return.
- */
-
- if (pjob->status == LPQ_DELETING)
- return True;
-
- /* Hrm - we need to be able to cope with deleting a job before it
- has reached the spooler. */
-
- if (pjob->sysjob == -1) {
- DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
- }
-
- /* Set the tdb entry to be deleting. */
-
- pjob->status = LPQ_DELETING;
- pjob_store(snum, jobid, pjob);
-
- if (pjob->spooled && pjob->sysjob != -1)
- result = (*(current_printif->job_delete))(snum, pjob);
-
- /* Delete the tdb entry if the delete suceeded or the job hasn't
- been spooled. */
-
- if (result == 0)
- pjob_delete(snum, jobid);
-
- return (result == 0);
-}
-
-/****************************************************************************
- Return true if the current user owns the print job.
-****************************************************************************/
-
-static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- user_struct *vuser;
-
- if (!pjob || !user)
- return False;
-
- if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
- return strequal(pjob->user, vuser->user.smb_name);
- } else {
- return strequal(pjob->user, uidtoname(user->uid));
- }
-}
-
-/****************************************************************************
- Delete a print job.
-****************************************************************************/
-
-BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
-{
- BOOL owner, deleted;
- char *fname;
-
- *errcode = WERR_OK;
-
- owner = is_owner(user, snum, jobid);
-
- /* Check access against security descriptor or whether the user
- owns their job. */
-
- if (!owner &&
- !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
- DEBUG(3, ("delete denied by security descriptor\n"));
- *errcode = WERR_ACCESS_DENIED;
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
-
- return False;
- }
-
- /*
- * get the spooled filename of the print job
- * if this works, then the file has not been spooled
- * to the underlying print system. Just delete the
- * spool file & return.
- */
-
- if ( (fname = print_job_fname( snum, jobid )) != NULL )
- {
- /* remove the spool file */
- DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
- if ( unlink( fname ) == -1 ) {
- *errcode = map_werror_from_unix(errno);
- return False;
- }
-
- return True;
- }
-
- if (!print_job_delete1(snum, jobid)) {
- *errcode = WERR_ACCESS_DENIED;
- return False;
- }
-
- /* force update the database and say the delete failed if the
- job still exists */
-
- print_queue_update(snum);
-
- deleted = !print_job_exists(snum, jobid);
- if ( !deleted )
- *errcode = WERR_ACCESS_DENIED;
-
- return deleted;
-}
-
-/****************************************************************************
- Pause a job.
-****************************************************************************/
-
-BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret = -1;
-
- if (!pjob || !user)
- return False;
-
- if (!pjob->spooled || pjob->sysjob == -1)
- return False;
-
- if (!is_owner(user, snum, jobid) &&
- !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
- DEBUG(3, ("pause denied by security descriptor\n"));
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
-
- *errcode = WERR_ACCESS_DENIED;
- return False;
- }
-
- /* need to pause the spooled entry */
- ret = (*(current_printif->job_pause))(snum, pjob);
-
- if (ret != 0) {
- *errcode = WERR_INVALID_PARAM;
- return False;
- }
-
- /* force update the database */
- print_cache_flush(snum);
-
- /* Send a printer notify message */
-
- notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
-
- /* how do we tell if this succeeded? */
-
- return True;
-}
-
-/****************************************************************************
- Resume a job.
-****************************************************************************/
-
-BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret;
-
- if (!pjob || !user)
- return False;
-
- if (!pjob->spooled || pjob->sysjob == -1)
- return False;
-
- if (!is_owner(user, snum, jobid) &&
- !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
- DEBUG(3, ("resume denied by security descriptor\n"));
- *errcode = WERR_ACCESS_DENIED;
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
- return False;
- }
-
- ret = (*(current_printif->job_resume))(snum, pjob);
-
- if (ret != 0) {
- *errcode = WERR_INVALID_PARAM;
- return False;
- }
-
- /* force update the database */
- print_cache_flush(snum);
-
- /* Send a printer notify message */
-
- notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
-
- return True;
-}
-
-/****************************************************************************
- Write to a print file.
-****************************************************************************/
-
-int print_job_write(int snum, uint32 jobid, const char *buf, int size)
-{
- int return_code;
- struct printjob *pjob = print_job_find(snum, jobid);
-
- if (!pjob)
- return -1;
- /* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != local_pid)
- return -1;
-
- return_code = write(pjob->fd, buf, size);
- if (return_code>0) {
- pjob->size += size;
- pjob_store(snum, jobid, pjob);
- }
- return return_code;
-}
-
-/****************************************************************************
- Check if the print queue has been updated recently enough.
-****************************************************************************/
-
-static BOOL print_cache_expired(int snum)
-{
- fstring key;
- time_t last_qscan_time, time_now = time(NULL);
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return False;
-
- slprintf(key, sizeof(key), "CACHE/%s", printername);
- last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
-
- /*
- * Invalidate the queue for 3 reasons.
- * (1). last queue scan time == -1.
- * (2). Current time - last queue scan time > allowed cache time.
- * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
- * This last test picks up machines for which the clock has been moved
- * forward, an lpq scan done and then the clock moved back. Otherwise
- * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
- */
-
- if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
- last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
- DEBUG(3, ("print cache expired for queue %s \
-(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
- (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
- release_print_db(pdb);
- return True;
- }
- release_print_db(pdb);
- return False;
-}
-
-/****************************************************************************
- Get the queue status - do not update if db is out of date.
-****************************************************************************/
-
-static int get_queue_status(int snum, print_status_struct *status)
-{
- fstring keystr;
- TDB_DATA data, key;
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
- int len;
-
- if (!pdb)
- return 0;
-
- if (status) {
- ZERO_STRUCTP(status);
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
- data = tdb_fetch(pdb->tdb, key);
- if (data.dptr) {
- if (data.dsize == sizeof(print_status_struct))
- memcpy(status, data.dptr, sizeof(print_status_struct));
- SAFE_FREE(data.dptr);
- }
- }
- len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
- release_print_db(pdb);
- return (len == -1 ? 0 : len);
-}
-
-/****************************************************************************
- Determine the number of jobs in a queue.
-****************************************************************************/
-
-int print_queue_length(int snum, print_status_struct *pstatus)
-{
- print_status_struct status;
- int len;
-
- /* make sure the database is up to date */
- if (print_cache_expired(snum))
- print_queue_update(snum);
-
- /* also fetch the queue status */
- memset(&status, 0, sizeof(status));
- len = get_queue_status(snum, &status);
-
- if (pstatus)
- *pstatus = status;
-
- return len;
-}
-
-/***************************************************************************
- Allocate a jobid. Hold the lock for as short a time as possible.
-***************************************************************************/
-
-static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
-{
- int i;
- uint32 jobid;
-
- *pjobid = (uint32)-1;
-
- for (i = 0; i < 3; i++) {
- /* Lock the database - only wait 20 seconds. */
- if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
- DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
- return False;
- }
-
- if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
- if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
- DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
- printername ));
- return False;
- }
- jobid = 0;
- }
-
- jobid = NEXT_JOBID(jobid);
-
- if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
- DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
- tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
- return False;
- }
-
- /* We've finished with the INFO/nextjob lock. */
- tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
-
- if (!print_job_exists(snum, jobid))
- break;
- }
-
- if (i > 2) {
- DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
- printername ));
- /* Probably full... */
- errno = ENOSPC;
- return False;
- }
-
- /* Store a dummy placeholder. */
- {
- TDB_DATA dum;
- dum.dptr = NULL;
- dum.dsize = 0;
- if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
- DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
- jobid ));
- return False;
- }
- }
-
- *pjobid = jobid;
- return True;
-}
-
-/***************************************************************************
- Start spooling a job - return the jobid.
-***************************************************************************/
-
-uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
-{
- uint32 jobid;
- char *path;
- struct printjob pjob;
- user_struct *vuser;
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
- int njobs;
-
- errno = 0;
-
- if (!pdb)
- return (uint32)-1;
-
- if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
- DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
- release_print_db(pdb);
- return (uint32)-1;
- }
-
- if (!print_time_access_check(snum)) {
- DEBUG(3, ("print_job_start: job start denied by time check\n"));
- release_print_db(pdb);
- return (uint32)-1;
- }
-
- path = lp_pathname(snum);
-
- /* see if we have sufficient disk space */
- if (lp_minprintspace(snum)) {
- SMB_BIG_UINT dspace, dsize;
- if (sys_fsusage(path, &dspace, &dsize) == 0 &&
- dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
- DEBUG(3, ("print_job_start: disk space check failed.\n"));
- release_print_db(pdb);
- errno = ENOSPC;
- return (uint32)-1;
- }
- }
-
- /* for autoloaded printers, check that the printcap entry still exists */
- if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
- DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
- release_print_db(pdb);
- errno = ENOENT;
- return (uint32)-1;
- }
-
- /* Insure the maximum queue size is not violated */
- if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
- DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
- printername, njobs, lp_maxprintjobs(snum) ));
- release_print_db(pdb);
- errno = ENOSPC;
- return (uint32)-1;
- }
-
- DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
- printername, njobs, lp_maxprintjobs(snum) ));
-
- if (!allocate_print_jobid(pdb, snum, printername, &jobid))
- goto fail;
-
- /* create the database entry */
-
- ZERO_STRUCT(pjob);
-
- pjob.pid = local_pid;
- pjob.sysjob = -1;
- pjob.fd = -1;
- pjob.starttime = time(NULL);
- pjob.status = LPQ_SPOOLING;
- pjob.size = 0;
- pjob.spooled = False;
- pjob.smbjob = True;
- pjob.nt_devmode = nt_devmode;
-
- fstrcpy(pjob.jobname, jobname);
-
- if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
- fstrcpy(pjob.user, vuser->user.smb_name);
- } else {
- fstrcpy(pjob.user, uidtoname(user->uid));
- }
-
- fstrcpy(pjob.queuename, lp_const_servicename(snum));
-
- /* we have a job entry - now create the spool file */
- slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
- path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
- pjob.fd = smb_mkstemp(pjob.filename);
-
- if (pjob.fd == -1) {
- if (errno == EACCES) {
- /* Common setup error, force a report. */
- DEBUG(0, ("print_job_start: insufficient permissions \
-to open spool file %s.\n", pjob.filename));
- } else {
- /* Normal case, report at level 3 and above. */
- DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
- DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
- }
- goto fail;
- }
-
- pjob_store(snum, jobid, &pjob);
-
- /* Ensure we keep a rough count of the number of total jobs... */
- tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
-
- release_print_db(pdb);
-
- return jobid;
-
- fail:
- if (jobid != -1)
- pjob_delete(snum, jobid);
-
- release_print_db(pdb);
-
- DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
- return (uint32)-1;
-}
-
-/****************************************************************************
- Update the number of pages spooled to jobid
-****************************************************************************/
-
-void print_job_endpage(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- if (!pjob)
- return;
- /* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != local_pid)
- return;
-
- pjob->page_count++;
- pjob_store(snum, jobid, pjob);
-}
-
-/****************************************************************************
- Print a file - called on closing the file. This spools the job.
- If normal close is false then we're tearing down the jobs - treat as an
- error.
-****************************************************************************/
-
-BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret;
- SMB_STRUCT_STAT sbuf;
-
- if (!pjob)
- return False;
-
- if (pjob->spooled || pjob->pid != local_pid)
- return False;
-
- if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
- pjob->size = sbuf.st_size;
- close(pjob->fd);
- pjob->fd = -1;
- } else {
-
- /*
- * Not a normal close or we couldn't stat the job file,
- * so something has gone wrong. Cleanup.
- */
- close(pjob->fd);
- pjob->fd = -1;
- DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
- goto fail;
- }
-
- /* Technically, this is not quite right. If the printer has a separator
- * page turned on, the NT spooler prints the separator page even if the
- * print job is 0 bytes. 010215 JRR */
- if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
- /* don't bother spooling empty files or something being deleted. */
- DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
- pjob->filename, pjob->size ? "deleted" : "zero length" ));
- unlink(pjob->filename);
- pjob_delete(snum, jobid);
- return True;
- }
-
- ret = (*(current_printif->job_submit))(snum, pjob);
-
- if (ret)
- goto fail;
-
- /* The print job has been sucessfully handed over to the back-end */
-
- pjob->spooled = True;
- pjob->status = LPQ_QUEUED;
- pjob_store(snum, jobid, pjob);
-
- /* make sure the database is up to date */
- if (print_cache_expired(snum))
- print_queue_update(snum);
-
- return True;
-
-fail:
-
- /* The print job was not succesfully started. Cleanup */
- /* Still need to add proper error return propagation! 010122:JRR */
- unlink(pjob->filename);
- pjob_delete(snum, jobid);
- return False;
-}
-
-/****************************************************************************
- Utility fn to enumerate the print queue.
-****************************************************************************/
-
-static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct traverse_struct *ts = (struct traverse_struct *)state;
- struct printjob pjob;
- int i;
- uint32 jobid;
-
- /* sanity checks */
-
- if ( key.dsize != sizeof(jobid) )
- return 0;
-
- memcpy(&jobid, key.dptr, sizeof(jobid));
-
- if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
- return 0;
- free_nt_devicemode( &pjob.nt_devmode );
-
- /* maybe it isn't for this queue */
- if (ts->snum != lp_servicenumber(pjob.queuename))
- return 0;
-
- if (ts->qcount >= ts->maxcount)
- return 0;
-
- i = ts->qcount;
-
- ts->queue[i].job = jobid;
- ts->queue[i].size = pjob.size;
- ts->queue[i].page_count = pjob.page_count;
- ts->queue[i].status = pjob.status;
- ts->queue[i].priority = 1;
- ts->queue[i].time = pjob.starttime;
- fstrcpy(ts->queue[i].fs_user, pjob.user);
- fstrcpy(ts->queue[i].fs_file, pjob.jobname);
-
- ts->qcount++;
-
- return 0;
-}
-
-struct traverse_count_struct {
- int snum, count;
-};
-
-/****************************************************************************
- Utility fn to count the number of entries in the print queue.
-****************************************************************************/
-
-static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
- struct printjob pjob;
- uint32 jobid;
-
- /* sanity checks */
-
- if ( key.dsize != sizeof(jobid) )
- return 0;
-
- memcpy(&jobid, key.dptr, sizeof(jobid));
-
- if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
- return 0;
-
- free_nt_devicemode( &pjob.nt_devmode );
-
- /* maybe it isn't for this queue - this cannot happen with the tdb/printer code. JRA */
- if (ts->snum != lp_servicenumber(pjob.queuename))
- return 0;
-
- ts->count++;
-
- return 0;
-}
-
-/****************************************************************************
- Sort print jobs by submittal time.
-****************************************************************************/
-
-static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
-{
- /* Silly cases */
-
- if (!j1 && !j2)
- return 0;
- if (!j1)
- return -1;
- if (!j2)
- return 1;
-
- /* Sort on job start time */
-
- if (j1->time == j2->time)
- return 0;
- return (j1->time > j2->time) ? 1 : -1;
-}
-
-/****************************************************************************
- Get a printer queue listing.
- set queue = NULL and status = NULL if you just want to update the cache
-****************************************************************************/
-
-int print_queue_status(int snum,
- print_queue_struct **queue,
- print_status_struct *status)
-{
- struct traverse_struct tstruct;
- struct traverse_count_struct tsc;
- fstring keystr;
- TDB_DATA data, key;
- const char *printername;
- struct tdb_print_db *pdb;
-
- /* make sure the database is up to date */
-
- if (print_cache_expired(snum))
- print_queue_update(snum);
-
- /* return if we are done */
-
- if ( !queue || !status )
- return 0;
-
- *queue = NULL;
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return 0;
-
- /*
- * Fetch the queue status. We must do this first, as there may
- * be no jobs in the queue.
- */
- ZERO_STRUCTP(status);
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
- data = tdb_fetch(pdb->tdb, key);
- if (data.dptr) {
- if (data.dsize == sizeof(*status)) {
- memcpy(status, data.dptr, sizeof(*status));
- }
- SAFE_FREE(data.dptr);
- }
-
- /*
- * Now, fetch the print queue information. We first count the number
- * of entries, and then only retrieve the queue if necessary.
- */
- tsc.count = 0;
- tsc.snum = snum;
-
- tdb_traverse(pdb->tdb, traverse_count_fn_queue, (void *)&tsc);
-
- if (tsc.count == 0) {
- release_print_db(pdb);
- return 0;
- }
-
- /* Allocate the queue size. */
- if ((tstruct.queue = (print_queue_struct *)
- malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) {
- release_print_db(pdb);
- return 0;
- }
-
- /*
- * Fill in the queue.
- * We need maxcount as the queue size may have changed between
- * the two calls to tdb_traverse.
- */
- tstruct.qcount = 0;
- tstruct.maxcount = tsc.count;
- tstruct.snum = snum;
-
- tdb_traverse(pdb->tdb, traverse_fn_queue, (void *)&tstruct);
- release_print_db(pdb);
-
- /* Sort the queue by submission time otherwise they are displayed
- in hash order. */
-
- qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
- QSORT_CAST printjob_comp);
-
- *queue = tstruct.queue;
- return tstruct.qcount;
-}
-
-/****************************************************************************
- Pause a queue.
-****************************************************************************/
-
-BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
-{
- int ret;
-
- if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
- *errcode = WERR_ACCESS_DENIED;
- return False;
- }
-
- ret = (*(current_printif->queue_pause))(snum);
-
- if (ret != 0) {
- *errcode = WERR_INVALID_PARAM;
- return False;
- }
-
- /* force update the database */
- print_cache_flush(snum);
-
- /* Send a printer notify message */
-
- notify_printer_status(snum, PRINTER_STATUS_PAUSED);
-
- return True;
-}
-
-/****************************************************************************
- Resume a queue.
-****************************************************************************/
-
-BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
-{
- int ret;
-
- if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
- *errcode = WERR_ACCESS_DENIED;
- return False;
- }
-
- ret = (*(current_printif->queue_resume))(snum);
-
- if (ret != 0) {
- *errcode = WERR_INVALID_PARAM;
- return False;
- }
-
- /* make sure the database is up to date */
- if (print_cache_expired(snum))
- print_queue_update(snum);
-
- /* Send a printer notify message */
-
- notify_printer_status(snum, PRINTER_STATUS_OK);
-
- return True;
-}
-
-/****************************************************************************
- Purge a queue - implemented by deleting all jobs that we can delete.
-****************************************************************************/
-
-BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
-{
- print_queue_struct *queue;
- print_status_struct status;
- int njobs, i;
- BOOL can_job_admin;
-
- /* Force and update so the count is accurate (i.e. not a cached count) */
- print_queue_update(snum);
-
- can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
- njobs = print_queue_status(snum, &queue, &status);
-
- for (i=0;i<njobs;i++) {
- BOOL owner = is_owner(user, snum, queue[i].job);
-
- if (owner || can_job_admin) {
- print_job_delete1(snum, queue[i].job);
- }
- }
-
- SAFE_FREE(queue);
-
- return True;
-}
diff --git a/source4/printing/printing_db.c b/source4/printing/printing_db.c
deleted file mode 100644
index 0aa8dfafa5..0000000000
--- a/source4/printing/printing_db.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- printing backend routines
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Jeremy Allison 2002
-
- 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 "printing.h"
-
-static struct tdb_print_db *print_db_head;
-
-/****************************************************************************
- Function to find or create the printer specific job tdb given a printername.
- Limits the number of tdb's open to MAX_PRINT_DBS_OPEN.
-****************************************************************************/
-
-struct tdb_print_db *get_print_db_byname(const char *printername)
-{
- struct tdb_print_db *p = NULL, *last_entry = NULL;
- int num_open = 0;
- pstring printdb_path;
- BOOL done_become_root = False;
-
- for (p = print_db_head, last_entry = print_db_head; p; p = p->next) {
- /* Ensure the list terminates... JRA. */
- SMB_ASSERT(p->next != print_db_head);
-
- if (p->tdb && strequal(p->printer_name, printername)) {
- DLIST_PROMOTE(print_db_head, p);
- p->ref_count++;
- return p;
- }
- num_open++;
- last_entry = p;
- }
-
- /* Not found. */
- if (num_open >= MAX_PRINT_DBS_OPEN) {
- /* Try and recycle the last entry. */
- DLIST_PROMOTE(print_db_head, last_entry);
-
- for (p = print_db_head; p; p = p->next) {
- if (p->ref_count)
- continue;
- if (p->tdb) {
- if (tdb_close(print_db_head->tdb)) {
- DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
- print_db_head->printer_name ));
- return NULL;
- }
- }
- p->tdb = NULL;
- p->ref_count = 0;
- memset(p->printer_name, '\0', sizeof(p->printer_name));
- break;
- }
- if (p) {
- DLIST_PROMOTE(print_db_head, p);
- p = print_db_head;
- }
- }
-
- if (!p) {
- /* Create one. */
- p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db));
- if (!p) {
- DEBUG(0,("get_print_db: malloc fail !\n"));
- return NULL;
- }
- ZERO_STRUCTP(p);
- DLIST_ADD(print_db_head, p);
- }
-
- pstrcpy(printdb_path, lock_path("printing/"));
- pstrcat(printdb_path, printername);
- pstrcat(printdb_path, ".tdb");
-
- if (geteuid() != 0) {
- become_root();
- done_become_root = True;
- }
-
- p->tdb = tdb_open_log(printdb_path, 5000, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-
- if (done_become_root)
- unbecome_root();
-
- if (!p->tdb) {
- DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
- printdb_path ));
- DLIST_REMOVE(print_db_head, p);
- SAFE_FREE(p);
- return NULL;
- }
- fstrcpy(p->printer_name, printername);
- p->ref_count++;
- return p;
-}
-
-/***************************************************************************
- Remove a reference count.
-****************************************************************************/
-
-void release_print_db( struct tdb_print_db *pdb)
-{
- pdb->ref_count--;
- SMB_ASSERT(pdb->ref_count >= 0);
-}
-
-/***************************************************************************
- Close all open print db entries.
-****************************************************************************/
-
-void close_all_print_db(void)
-{
- struct tdb_print_db *p = NULL, *next_p = NULL;
-
- for (p = print_db_head; p; p = next_p) {
- next_p = p->next;
-
- if (p->tdb)
- tdb_close(p->tdb);
- DLIST_REMOVE(print_db_head, p);
- ZERO_STRUCTP(p);
- SAFE_FREE(p);
- }
-}
-
-
-/****************************************************************************
- Fetch and clean the pid_t record list for all pids interested in notify
- messages. data needs freeing on exit.
-****************************************************************************/
-
-TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist)
-{
- TDB_DATA data;
- size_t i;
-
- ZERO_STRUCT(data);
-
- data = tdb_fetch_by_string( tdb, NOTIFY_PID_LIST_KEY );
-
- if (!data.dptr) {
- ZERO_STRUCT(data);
- return data;
- }
-
- if (data.dsize % 8) {
- DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name ));
- tdb_delete_by_string(tdb, NOTIFY_PID_LIST_KEY );
- SAFE_FREE(data.dptr);
- ZERO_STRUCT(data);
- return data;
- }
-
- if (!cleanlist)
- return data;
-
- /*
- * Weed out all dead entries.
- */
-
- for( i = 0; i < data.dsize; i += 8) {
- pid_t pid = (pid_t)IVAL(data.dptr, i);
-
- if (pid == sys_getpid())
- continue;
-
- /* Entry is dead if process doesn't exist or refcount is zero. */
-
- while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid))) {
-
- /* Refcount == zero is a logic error and should never happen. */
- if (IVAL(data.dptr, i + 4) == 0) {
- DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n",
- (unsigned int)pid, printer_name ));
- }
-
- if (data.dsize - i > 8)
- memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
- data.dsize -= 8;
- }
- }
-
- return data;
-}
-
-
diff --git a/source4/smbwrapper/PORTING b/source4/smbwrapper/PORTING
deleted file mode 100644
index 884246d078..0000000000
--- a/source4/smbwrapper/PORTING
+++ /dev/null
@@ -1,77 +0,0 @@
-This describes how to port the smbwrapper portion of Samba to a new
-unix-like platform. Note that porting smbwrapper is considerably
-harder than porting Samba, for Samba you generally just need to run
-configure and recompile whereas for smbwrapper some extra effort is
-generally required.
-
-
-STEP 1
-------
-
-The first step is to work out how to create a shared library on your
-OS and how to compile C code to produce position independent object
-files (PIC files). You shoud be able to find this information in the
-man pages for your compiler and loader (ld). Then modify configure.in
-to give that information to Samba.
-
-
-STEP 2
-------
-
-The next step is to work out how to preload shared objects. On many
-systems this is done using a LD_PRELOAD environment variable. On
-others (shc as IRIX) it may use a _RTL_LIST variable.
-
-To make sure it works I suggest you create two C files like this:
-
-/* first C file */
-main()
-{
- unlink("foo.txt");
-}
-
-/* second C file */
-#include <stdio.h>
-
-int unlink(char *fname)
-{
- fprintf(stderr,"unlink(%s) called\n",fname);
-}
-
-
-then compile the first as an ordinary C program and the second as a
-shared library. Then use LD_PRELOAD to preload the resulting shared
-library. Then run the first program. It should print "unlink(foo.txt)
-called". If it doesn't then consult your man pages till you get it
-right.
-
-Once you work this out then edit smbwrapper/smbsh.in and add a section
-if necessary to correctly set the necessary preload options for your
-OS.
-
-
-STEP 3
-------
-
-The next step is to work out how to make direct system calls. On most
-machines this will work without any source code changes to
-smbwrapper. To test that it does work create the following C program:
-
-#include <sys/syscall.h>
-main()
-{
- syscall(SYS_write, 1, "hello world\n", 12);
-}
-
-and try to compile/run it. If it produces "hello world" then syscall()
-works as expected. If not then work out what needs to be changed and
-then make that change in realcalls.h. For example, on IRIX 6.4 the
-system call numbers are wrong and need to be fixed up by getting an
-offset right.
-
-
-STEP 4
-------
-
-Try compiling smbwrapper! Then test it. Then debug it. Simple really :)
-
diff --git a/source4/smbwrapper/README b/source4/smbwrapper/README
deleted file mode 100644
index 8d5c376f82..0000000000
--- a/source4/smbwrapper/README
+++ /dev/null
@@ -1,94 +0,0 @@
-This is a prelodable shared library that provides SMB client services
-for existing executables. Using this you can simulate a smb
-filesystem.
-
-*** This is code under development. Some things don't work yet ***
-
-Currently this code has been tested on:
-
-- Linux 2.0 with glibc2 (RH5.1)
-- Linux 2.1 with glibc2
-- Solaris 2.5.1 with gcc
-- Solaris 2.6 with gcc
-- SunOS 4.1.3 with gcc
-- IRIX 6.4 with cc
-- OSF1 with gcc
-
-
-It probably won't run on other systems without some porting. If you
-have a different system then see the file PORTING.
-
-To use it you need to do this:
-
-1) build smbwrapper.so using the command "make smbwrapper"
-3) run smbsh
-
-You will be asked for a username and password. After that you will be
-returned to a shell prompt. It is actually a subshell running with
-smbwrapper enabled.
-
-Now try to access /smb/SERVER for some SMB server name and see what
-happens. If you use the -W option to set your workgroup or have
-workgroup set in your smb.conf then listing /smb/ should list all SMB
-servers in your workgroup.
-
-
-OPTIONS
--------
-
--U username
- specify the username and optional password (as user%password)
-
--d debug level
- This is an integer that controls the internal debug level of smbw. It
- defaults to 0, which means no debug info.
-
--l logfile
- The place where smbw debug logs are put. If this is not set then
- stderr is used.
-
--P prefix
- The root of the SMB filesystem. This defaults to /smb/ but you can
- set it to any name you like.
-
--W workgroup
- This is the workgroup used for browsing (ie. listing machines in the
- /smb/ directory). It defaults to the one set in smb.conf.
-
--R resolve order
- This allows you to override the setting of the name resolve order
- from smb.conf
-
-
-ATTRIBUTE MAPPING
------------------
-
-smbwrapper does an inverse attribute maping to what Samba does. This
-means that the archive bit appears as the user execute bit, the system
-bit appears as the group execute bit and the hidden bit appears as the
-other execute bit. You can control these with chmod. The mapping can
-be enabled an disabled using the normal smb.conf controls (ie. "map
-archive", "map system" and "map hidden").
-
-Read-only files appear as non-writeable by everyone. Writeable files
-appear as writeable by the current user.
-
-
-WHAT WORKS
-----------
-
-Things that I have tried and do seem to work include:
-
- emacs, tar, ls, cmp, cp, rsync, du, cat, rm, mv, less, more, wc, head,
- tail, bash, tcsh, mkdir, rmdir, vim, xedit, diff
-
-things that I know don't work:
-
- anything executing from the share
- anything that uses mmap
- redirection within shells to smbsh files
-
-If you want to help with the development of this code then join the
-samba-technical mailing list.
-
-
diff --git a/source4/smbwrapper/realcalls.c b/source4/smbwrapper/realcalls.c
deleted file mode 100644
index b64f4a43db..0000000000
--- a/source4/smbwrapper/realcalls.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB wrapper functions for calls that syscall() can't do
- Copyright (C) Andrew Tridgell 1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "realcalls.h"
-
-#ifdef REPLACE_UTIME
-int real_utime(const char *name, struct utimbuf *buf)
-{
- struct timeval tv[2];
-
- tv[0].tv_sec = buf->actime;
- tv[0].tv_usec = 0;
- tv[1].tv_sec = buf->modtime;
- tv[1].tv_usec = 0;
-
- return real_utimes(name, &tv[0]);
-}
-#endif
-
-#ifdef REPLACE_UTIMES
-int real_utimes(const char *name, struct timeval tv[2])
-{
- struct utimbuf buf;
-
- buf.actime = tv[0].tv_sec;
- buf.modtime = tv[1].tv_sec;
-
- return real_utime(name, &buf);
-}
-#endif
diff --git a/source4/smbwrapper/realcalls.h b/source4/smbwrapper/realcalls.h
deleted file mode 100644
index 6c230dba05..0000000000
--- a/source4/smbwrapper/realcalls.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- defintions of syscall entries
- Copyright (C) Andrew Tridgell 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.
-*/
-
-#if HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
-#elif HAVE_SYSCALL_H
-#include <syscall.h>
-#endif
-
-#ifdef IRIX
-/* amazingly, IRIX gets its own syscall numbers wrong! */
-#ifdef SYSVoffset
-#if (SYSVoffset == 1)
-#undef SYSVoffset
-#define SYSVoffset 1000
-#endif
-#endif
-#endif
-
-/* this file is partly derived from zlibc by Alain Knaff */
-
-#define real_access(fn, mode) (syscall(SYS_access, (fn), (mode)))
-#define real_chdir(fn) (syscall(SYS_chdir, (fn)))
-#define real_chmod(fn, mode) (syscall(SYS_chmod,(fn), (mode)))
-#define real_chown(fn, owner, group) (syscall(SYS_chown,(fn),(owner),(group)))
-
-#ifdef SYS_getdents
-#define real_getdents(fd, dirp, count) (syscall(SYS_getdents, (fd), (dirp), (count)))
-#endif
-
-#define real_link(fn1, fn2) (syscall(SYS_link, (fn1), (fn2)))
-
-#define real_open(fn,flags,mode) (syscall(SYS_open, (fn), (flags), (mode)))
-
-#ifdef SYS_open64
-#define real_open64(fn,flags,mode) (syscall(SYS_open64, (fn), (flags), (mode)))
-#elif HAVE__OPEN64
-#define real_open64(fn,flags,mode) (_open64(fn,flags,mode))
-#define NO_OPEN64_ALIAS
-#elif HAVE___OPEN64
-#define real_open64(fn,flags,mode) (__open64(fn,flags,mode))
-#define NO_OPEN64_ALIAS
-#endif
-
-#ifdef HAVE__FORK
-#define real_fork() (_fork())
-#elif HAVE___FORK
-#define real_fork() (__fork())
-#elif SYS_fork
-#define real_fork() (syscall(SYS_fork))
-#endif
-
-#ifdef HAVE__OPENDIR
-#define real_opendir(fn) (_opendir(fn))
-#elif SYS_opendir
-#define real_opendir(fn) (syscall(SYS_opendir,(fn)))
-#elif HAVE___OPENDIR
-#define real_opendir(fn) (__opendir(fn))
-#endif
-
-#ifdef HAVE__READDIR
-#define real_readdir(d) (_readdir(d))
-#elif HAVE___READDIR
-#define real_readdir(d) (__readdir(d))
-#elif SYS_readdir
-#define real_readdir(d) (syscall(SYS_readdir,(d)))
-#endif
-
-#ifdef HAVE__CLOSEDIR
-#define real_closedir(d) (_closedir(d))
-#elif SYS_closedir
-#define real_closedir(d) (syscall(SYS_closedir,(d)))
-#elif HAVE___CLOSEDIR
-#define real_closedir(d) (__closedir(d))
-#endif
-
-#ifdef HAVE__SEEKDIR
-#define real_seekdir(d,l) (_seekdir(d,l))
-#elif SYS_seekdir
-#define real_seekdir(d,l) (syscall(SYS_seekdir,(d),(l)))
-#elif HAVE___SEEKDIR
-#define real_seekdir(d,l) (__seekdir(d,l))
-#else
-#define NO_SEEKDIR_WRAPPER
-#endif
-
-#ifdef HAVE__TELLDIR
-#define real_telldir(d) (_telldir(d))
-#elif SYS_telldir
-#define real_telldir(d) (syscall(SYS_telldir,(d)))
-#elif HAVE___TELLDIR
-#define real_telldir(d) (__telldir(d))
-#endif
-
-#ifdef HAVE__DUP
-#define real_dup(d) (_dup(d))
-#elif SYS_dup
-#define real_dup(d) (syscall(SYS_dup,(d)))
-#elif HAVE___DUP
-#define real_dup(d) (__dup(d))
-#endif
-
-#ifdef HAVE__DUP2
-#define real_dup2(d1,d2) (_dup2(d1,d2))
-#elif SYS_dup2
-#define real_dup2(d1,d2) (syscall(SYS_dup2,(d1),(d2)))
-#elif HAVE___DUP2
-#define real_dup2(d1,d2) (__dup2(d1,d2))
-#endif
-
-#ifdef HAVE__GETCWD
-#define real_getcwd(b,s) ((char *)_getcwd(b,s))
-#elif SYS_getcwd
-#define real_getcwd(b,s) ((char *)syscall(SYS_getcwd,(b),(s)))
-#elif HAVE___GETCWD
-#define real_getcwd(b,s) ((char *)__getcwd(b,s))
-#endif
-
-#ifdef HAVE__STAT
-#define real_stat(fn,st) (_stat(fn,st))
-#elif SYS_stat
-#define real_stat(fn,st) (syscall(SYS_stat,(fn),(st)))
-#elif HAVE___STAT
-#define real_stat(fn,st) (__stat(fn,st))
-#endif
-
-#ifdef HAVE__LSTAT
-#define real_lstat(fn,st) (_lstat(fn,st))
-#elif SYS_lstat
-#define real_lstat(fn,st) (syscall(SYS_lstat,(fn),(st)))
-#elif HAVE___LSTAT
-#define real_lstat(fn,st) (__lstat(fn,st))
-#endif
-
-#ifdef HAVE__FSTAT
-#define real_fstat(fd,st) (_fstat(fd,st))
-#elif SYS_fstat
-#define real_fstat(fd,st) (syscall(SYS_fstat,(fd),(st)))
-#elif HAVE___FSTAT
-#define real_fstat(fd,st) (__fstat(fd,st))
-#endif
-
-#if defined(HAVE_SYS_ACL_H) && defined(HAVE__ACL)
-#define real_acl(fn,cmd,n,buf) (_acl(fn,cmd,n,buf))
-#elif SYS_acl
-#define real_acl(fn,cmd,n,buf) (syscall(SYS_acl,(fn),(cmd),(n),(buf)))
-#elif HAVE___ACL
-#define real_acl(fn,cmd,n,buf) (__acl(fn,cmd,n,buf))
-#else
-#define NO_ACL_WRAPPER
-#endif
-
-#ifdef HAVE__FACL
-#define real_facl(fd,cmd,n,buf) (_facl(fd,cmd,n,buf))
-#elif SYS_facl
-#define real_facl(fd,cmd,n,buf) (syscall(SYS_facl,(fd),(cmd),(n),(buf)))
-#elif HAVE___FACL
-#define real_facl(fd,cmd,n,buf) (__facl(fd,cmd,n,buf))
-#else
-#define NO_FACL_WRAPPER
-#endif
-
-
-#ifdef HAVE__STAT64
-#define real_stat64(fn,st) (_stat64(fn,st))
-#elif HAVE___STAT64
-#define real_stat64(fn,st) (__stat64(fn,st))
-#endif
-
-#ifdef HAVE__LSTAT64
-#define real_lstat64(fn,st) (_lstat64(fn,st))
-#elif HAVE___LSTAT64
-#define real_lstat64(fn,st) (__lstat64(fn,st))
-#endif
-
-#ifdef HAVE__FSTAT64
-#define real_fstat64(fd,st) (_fstat64(fd,st))
-#elif HAVE___FSTAT64
-#define real_fstat64(fd,st) (__fstat64(fd,st))
-#endif
-
-#ifdef HAVE__READDIR64
-#define real_readdir64(d) (_readdir64(d))
-#elif HAVE___READDIR64
-#define real_readdir64(d) (__readdir64(d))
-#endif
-
-#ifdef HAVE__LLSEEK
-#define real_llseek(fd,ofs,whence) (_llseek(fd,ofs,whence))
-#elif HAVE___LLSEEK
-#define real_llseek(fd,ofs,whence) (__llseek(fd,ofs,whence))
-#elif HAVE___SYS_LLSEEK
-#define real_llseek(fd,ofs,whence) (__sys_llseek(fd,ofs,whence))
-#endif
-
-
-#ifdef HAVE__PREAD
-#define real_pread(fd,buf,size,ofs) (_pread(fd,buf,size,ofs))
-#elif HAVE___PREAD
-#define real_pread(fd,buf,size,ofs) (__pread(fd,buf,size,ofs))
-#endif
-
-#ifdef HAVE__PREAD64
-#define real_pread64(fd,buf,size,ofs) (_pread64(fd,buf,size,ofs))
-#elif HAVE___PREAD64
-#define real_pread64(fd,buf,size,ofs) (__pread64(fd,buf,size,ofs))
-#endif
-
-#ifdef HAVE__PWRITE
-#define real_pwrite(fd,buf,size,ofs) (_pwrite(fd,buf,size,ofs))
-#elif HAVE___PWRITE
-#define real_pwrite(fd,buf,size,ofs) (__pwrite(fd,buf,size,ofs))
-#endif
-
-#ifdef HAVE__PWRITE64
-#define real_pwrite64(fd,buf,size,ofs) (_pwrite64(fd,buf,size,ofs))
-#elif HAVE___PWRITE64
-#define real_pwrite64(fd,buf,size,ofs) (__pwrite64(fd,buf,size,ofs))
-#endif
-
-
-#define real_readlink(fn,buf,len) (syscall(SYS_readlink, (fn), (buf), (len)))
-#define real_rename(fn1, fn2) (syscall(SYS_rename, (fn1), (fn2)))
-#define real_symlink(fn1, fn2) (syscall(SYS_symlink, (fn1), (fn2)))
-#define real_read(fd, buf, count ) (syscall(SYS_read, (fd), (buf), (count)))
-#define real_lseek(fd, offset, whence) (syscall(SYS_lseek, (fd), (offset), (whence)))
-#define real_write(fd, buf, count ) (syscall(SYS_write, (fd), (buf), (count)))
-#define real_close(fd) (syscall(SYS_close, (fd)))
-#define real_fchdir(fd) (syscall(SYS_fchdir, (fd)))
-#define real_fcntl(fd,cmd,arg) (syscall(SYS_fcntl, (fd), (cmd), (arg)))
-#define real_symlink(fn1, fn2) (syscall(SYS_symlink, (fn1), (fn2)))
-#define real_unlink(fn) (syscall(SYS_unlink, (fn)))
-#define real_rmdir(fn) (syscall(SYS_rmdir, (fn)))
-#define real_mkdir(fn, mode) (syscall(SYS_mkdir, (fn), (mode)))
-
-#ifdef SYS_utime
-#define real_utime(fn, buf) (syscall(SYS_utime, (fn), (buf)))
-#else
-#define REPLACE_UTIME 1
-#endif
-
-#ifdef SYS_utimes
-#define real_utimes(fn, buf) (syscall(SYS_utimes, (fn), (buf)))
-#else
-#define REPLACE_UTIMES 1
-#endif
diff --git a/source4/smbwrapper/shared.c b/source4/smbwrapper/shared.c
deleted file mode 100644
index b4cfcf7148..0000000000
--- a/source4/smbwrapper/shared.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB wrapper functions - shared variables
- Copyright (C) Andrew Tridgell 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"
-
-static int shared_fd;
-static char *variables;
-static int shared_size;
-
-/*****************************************************
-setup the shared area
-*******************************************************/
-void smbw_setup_shared(void)
-{
- int fd;
- pstring name, s;
-
- slprintf(name,sizeof(name)-1, "%s/smbw.XXXXXX",tmpdir());
-
- fd = smb_mkstemp(name);
-
- if (fd == -1) goto failed;
-
- unlink(name);
-
- shared_fd = set_maxfiles(SMBW_MAX_OPEN);
-
- while (shared_fd && dup2(fd, shared_fd) != shared_fd) shared_fd--;
-
- if (shared_fd == 0) goto failed;
-
- close(fd);
-
- DEBUG(4,("created shared_fd=%d\n", shared_fd));
-
- slprintf(s,sizeof(s)-1,"%d", shared_fd);
-
- setenv("SMBW_HANDLE", s, 1);
-
- return;
-
- failed:
- perror("Failed to setup shared variable area ");
- exit(1);
-}
-
-static int locked;
-
-/*****************************************************
-lock the shared variable area
-*******************************************************/
-static void lockit(void)
-{
- if (shared_fd == 0) {
- char *p = getenv("SMBW_HANDLE");
- if (!p) {
- DEBUG(0,("ERROR: can't get smbw shared handle\n"));
- exit(1);
- }
- shared_fd = atoi(p);
- }
- if (locked==0 &&
- fcntl_lock(shared_fd,SMB_F_SETLKW,0,1,F_WRLCK)==False) {
- DEBUG(0,("ERROR: can't get smbw shared lock (%s)\n", strerror(errno)));
- exit(1);
- }
- locked++;
-}
-
-/*****************************************************
-unlock the shared variable area
-*******************************************************/
-static void unlockit(void)
-{
- locked--;
- if (locked == 0) {
- fcntl_lock(shared_fd,SMB_F_SETLK,0,1,F_UNLCK);
- }
-}
-
-
-/*****************************************************
-get a variable from the shared area
-*******************************************************/
-char *smbw_getshared(const char *name)
-{
- int i;
- struct stat st;
- char *var;
-
- lockit();
-
- /* maybe the area has changed */
- if (fstat(shared_fd, &st)) goto failed;
-
- if (st.st_size != shared_size) {
- var = (char *)Realloc(variables, st.st_size);
- if (!var) goto failed;
- else variables = var;
- shared_size = st.st_size;
- lseek(shared_fd, 0, SEEK_SET);
- if (read(shared_fd, variables, shared_size) != shared_size) {
- goto failed;
- }
- }
-
- unlockit();
-
- i=0;
- while (i < shared_size) {
- char *n, *v;
- int l1, l2;
-
- l1 = SVAL(&variables[i], 0);
- l2 = SVAL(&variables[i], 2);
-
- n = &variables[i+4];
- v = &variables[i+4+l1];
- i += 4+l1+l2;
-
- if (strcmp(name,n)) {
- continue;
- }
- return v;
- }
-
- return NULL;
-
- failed:
- DEBUG(0,("smbw: shared variables corrupt (%s)\n", strerror(errno)));
- exit(1);
- return NULL;
-}
-
-
-
-/*****************************************************
-set a variable in the shared area
-*******************************************************/
-void smbw_setshared(const char *name, const char *val)
-{
- int l1, l2;
- char *var;
-
- /* we don't allow variable overwrite */
- if (smbw_getshared(name)) return;
-
- lockit();
-
- l1 = strlen(name)+1;
- l2 = strlen(val)+1;
-
- var = (char *)Realloc(variables, shared_size + l1+l2+4);
-
- if (!var) {
- DEBUG(0,("out of memory in smbw_setshared\n"));
- exit(1);
- }
-
- variables = var;
-
- SSVAL(&variables[shared_size], 0, l1);
- SSVAL(&variables[shared_size], 2, l2);
-
- pstrcpy(&variables[shared_size] + 4, name);
- pstrcpy(&variables[shared_size] + 4 + l1, val);
-
- shared_size += l1+l2+4;
-
- lseek(shared_fd, 0, SEEK_SET);
- if (write(shared_fd, variables, shared_size) != shared_size) {
- DEBUG(0,("smbw_setshared failed (%s)\n", strerror(errno)));
- exit(1);
- }
-
- unlockit();
-}
-
-
-/*****************************************************************
-return true if the passed fd is the SMBW_HANDLE
-*****************************************************************/
-int smbw_shared_fd(int fd)
-{
- return (shared_fd && shared_fd == fd);
-}
diff --git a/source4/smbwrapper/smbsh.c b/source4/smbwrapper/smbsh.c
deleted file mode 100644
index 221c6d87c2..0000000000
--- a/source4/smbwrapper/smbsh.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB wrapper functions - frontend
- Copyright (C) Andrew Tridgell 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"
-
-static void smbsh_usage(void)
-{
- printf("smbsh [options]\n\n");
- printf(" -W workgroup\n");
- printf(" -U username\n");
- printf(" -P prefix\n");
- printf(" -R resolve order\n");
- printf(" -d debug level\n");
- printf(" -l logfile\n");
- printf(" -L libdir\n");
- exit(0);
-}
-
-int main(int argc, char *argv[])
-{
- char *p, *u;
- const char *libd = dyn_BINDIR;
- pstring line, wd;
- int opt;
- extern char *optarg;
- extern int optind;
-
- dbf = x_stdout;
- smbw_setup_shared();
-
- while ((opt = getopt(argc, argv, "W:U:R:d:P:l:hL:")) != EOF) {
- switch (opt) {
- case 'L':
- libd = optarg;
- break;
- case 'W':
- smbw_setshared("WORKGROUP", optarg);
- break;
- case 'l':
- smbw_setshared("LOGFILE", optarg);
- break;
- case 'P':
- smbw_setshared("PREFIX", optarg);
- break;
- case 'd':
- smbw_setshared("DEBUG", optarg);
- break;
- case 'U':
- p = strchr_m(optarg,'%');
- if (p) {
- *p=0;
- smbw_setshared("PASSWORD",p+1);
- }
- smbw_setshared("USER", optarg);
- break;
- case 'R':
- smbw_setshared("RESOLVE_ORDER",optarg);
- break;
-
- case 'h':
- default:
- smbsh_usage();
- }
- }
-
-
- if (!smbw_getshared("USER")) {
- printf("Username: ");
- u = fgets_slash(line, sizeof(line)-1, x_stdin);
- smbw_setshared("USER", u);
- }
-
- if (!smbw_getshared("PASSWORD")) {
- p = getpass("Password: ");
- smbw_setshared("PASSWORD", p);
- }
-
- setenv("PS1", "smbsh$ ", 1);
-
- sys_getwd(wd);
-
- slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
-
- smbw_setshared(line, wd);
-
- slprintf(line,sizeof(line)-1,"%s/smbwrapper.so", libd);
- setenv("LD_PRELOAD", line, 1);
-
- slprintf(line,sizeof(line)-1,"%s/smbwrapper.32.so", libd);
-
- if (file_exist(line, NULL)) {
- slprintf(line,sizeof(line)-1,"%s/smbwrapper.32.so:DEFAULT", libd);
- setenv("_RLD_LIST", line, 1);
- slprintf(line,sizeof(line)-1,"%s/smbwrapper.so:DEFAULT", libd);
- setenv("_RLDN32_LIST", line, 1);
- } else {
- slprintf(line,sizeof(line)-1,"%s/smbwrapper.so:DEFAULT", libd);
- setenv("_RLD_LIST", line, 1);
- }
-
- {
- char *shellpath = getenv("SHELL");
- if(shellpath)
- execl(shellpath,"smbsh",NULL);
- else
- execl("/bin/sh","smbsh",NULL);
- }
- printf("launch failed!\n");
- return 1;
-}
diff --git a/source4/smbwrapper/smbsh.in b/source4/smbwrapper/smbsh.in
deleted file mode 100644
index 323f091699..0000000000
--- a/source4/smbwrapper/smbsh.in
+++ /dev/null
@@ -1,54 +0,0 @@
-#! /bin/sh
-
-SMBW_LIBDIR=${SMBW_LIBDIR-@builddir@/smbwrapper}
-
-if [ ! -f ${SMBW_LIBDIR}/smbwrapper.so ]; then
- echo You need to set LIBDIR in smbsh
- exit
-fi
-
-# a simple launcher for the smbwrapper.so preloadde library
-
-if [ x"${SMBW_USER+set}" != x"set" ]; then
- echo username?
- read user
- SMBW_USER=$user
- export SMBW_USER
-fi
-
-# this doesn't hide the password - we need a proper launch app for that
-if [ x"${SMBW_PASSWORD+set}" != x"set" ]; then
- echo password?
- read pass
- SMBW_PASSWORD=$pass
- export SMBW_PASSWORD
-fi
-
-PWD=`pwd`
-export PWD
-PS1='smbsh$ '
-export PS1
-
-
-host_os=@HOST_OS@
-
-case "$host_os" in
- *irix*)
- _RLDN32_LIST=$SMBW_LIBDIR/smbwrapper.so:DEFAULT
- _RLD_LIST=$SMBW_LIBDIR/smbwrapper.32.so:DEFAULT
- export _RLDN32_LIST
- export _RLD_LIST
- ;;
- *osf*)
- _RLD_LIST=$SMBW_LIBDIR/smbwrapper.so:DEFAULT
- export _RLD_LIST
- ;;
- *)
- LD_PRELOAD=$SMBW_LIBDIR/smbwrapper.so
- export LD_PRELOAD
- ;;
-esac
-
-echo starting smbwrapper on $host_os
-
-exec ${SMBW_SHELL-${SHELL-/bin/sh}} ${1+"$@"}
diff --git a/source4/smbwrapper/smbw.c b/source4/smbwrapper/smbw.c
deleted file mode 100644
index c62533dc2a..0000000000
--- a/source4/smbwrapper/smbw.c
+++ /dev/null
@@ -1,1554 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB wrapper functions
- Copyright (C) Andrew Tridgell 1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "realcalls.h"
-
-pstring smbw_cwd;
-
-static struct smbw_file *smbw_files;
-static struct smbw_server *smbw_srvs;
-
-struct bitmap *smbw_file_bmap;
-
-fstring smbw_prefix = SMBW_PREFIX;
-
-int smbw_busy=0;
-
-/* needs to be here because of dumb include files on some systems */
-int creat_bits = O_WRONLY|O_CREAT|O_TRUNC;
-
-
-/*****************************************************
-initialise structures
-*******************************************************/
-void smbw_init(void)
-{
- extern BOOL in_client;
- static int initialised;
- char *p;
- int eno;
- pstring line;
-
- if (initialised) return;
- initialised = 1;
-
- eno = errno;
-
- smbw_busy++;
-
- DEBUGLEVEL = 0;
- setup_logging("smbsh", DEBUG_STDOUT);
-
- dbf = x_stderr;
-
- if ((p=smbw_getshared("LOGFILE"))) {
- dbf = sys_fopen(p, "a");
- }
-
- smbw_file_bmap = bitmap_allocate(SMBW_MAX_OPEN);
- if (!smbw_file_bmap) {
- exit(1);
- }
-
- in_client = True;
-
- load_interfaces();
-
- if ((p=smbw_getshared("SERVICESF"))) {
- pstrcpy(dyn_CONFIGFILE, p);
- }
-
- lp_load(dyn_CONFIGFILE,True,False,False);
-
- if (!init_names())
- exit(1);
-
- if ((p=smbw_getshared("DEBUG"))) {
- DEBUGLEVEL = atoi(p);
- }
-
- if ((p=smbw_getshared("RESOLVE_ORDER"))) {
- lp_set_name_resolve_order(p);
- }
-
- if ((p=smbw_getshared("PREFIX"))) {
- slprintf(smbw_prefix,sizeof(fstring)-1, "/%s/", p);
- all_string_sub(smbw_prefix,"//", "/", 0);
- DEBUG(2,("SMBW_PREFIX is %s\n", smbw_prefix));
- }
-
- slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
-
- p = smbw_getshared(line);
- if (!p) {
- sys_getwd(smbw_cwd);
- }
- pstrcpy(smbw_cwd, p);
- DEBUG(4,("Initial cwd is %s\n", smbw_cwd));
-
- smbw_busy--;
-
- set_maxfiles(SMBW_MAX_OPEN);
-
- BlockSignals(True,SIGPIPE);
-
- errno = eno;
-}
-
-/*****************************************************
-determine if a file descriptor is a smb one
-*******************************************************/
-int smbw_fd(int fd)
-{
- if (smbw_busy) return 0;
- return smbw_file_bmap && bitmap_query(smbw_file_bmap, fd);
-}
-
-/*****************************************************
-determine if a file descriptor is an internal smbw fd
-*******************************************************/
-int smbw_local_fd(int fd)
-{
- struct smbw_server *srv;
-
- smbw_init();
-
- if (smbw_busy) return 0;
- if (smbw_shared_fd(fd)) return 1;
-
- for (srv=smbw_srvs;srv;srv=srv->next) {
- if (srv->cli.fd == fd) return 1;
- }
-
- return 0;
-}
-
-/*****************************************************
-a crude inode number generator
-*******************************************************/
-ino_t smbw_inode(const char *name)
-{
- if (!*name) return 2;
- return (ino_t)str_checksum(name);
-}
-
-/*****************************************************
-remove redundent stuff from a filename
-*******************************************************/
-void clean_fname(char *name)
-{
- char *p, *p2;
- int l;
- int modified = 1;
-
- if (!name) return;
-
- while (modified) {
- modified = 0;
-
- DEBUG(5,("cleaning %s\n", name));
-
- if ((p=strstr(name,"/./"))) {
- modified = 1;
- while (*p) {
- p[0] = p[2];
- p++;
- }
- }
-
- if ((p=strstr(name,"//"))) {
- modified = 1;
- while (*p) {
- p[0] = p[1];
- p++;
- }
- }
-
- if (strcmp(name,"/../")==0) {
- modified = 1;
- name[1] = 0;
- }
-
- if ((p=strstr(name,"/../"))) {
- modified = 1;
- for (p2=(p>name?p-1:p);p2>name;p2--) {
- if (p2[0] == '/') break;
- }
- while (*p2) {
- p2[0] = p2[3];
- p2++;
- }
- }
-
- if (strcmp(name,"/..")==0) {
- modified = 1;
- name[1] = 0;
- }
-
- l = strlen(name);
- p = l>=3?(name+l-3):name;
- if (strcmp(p,"/..")==0) {
- modified = 1;
- for (p2=p-1;p2>name;p2--) {
- if (p2[0] == '/') break;
- }
- if (p2==name) {
- p[0] = '/';
- p[1] = 0;
- } else {
- p2[0] = 0;
- }
- }
-
- l = strlen(name);
- p = l>=2?(name+l-2):name;
- if (strcmp(p,"/.")==0) {
- if (p == name) {
- p[1] = 0;
- } else {
- p[0] = 0;
- }
- }
-
- if (strncmp(p=name,"./",2) == 0) {
- modified = 1;
- do {
- p[0] = p[2];
- } while (*p++);
- }
-
- l = strlen(p=name);
- if (l > 1 && p[l-1] == '/') {
- modified = 1;
- p[l-1] = 0;
- }
- }
-}
-
-
-
-/*****************************************************
-find a workgroup (any workgroup!) that has a master
-browser on the local network
-*******************************************************/
-static char *smbw_find_workgroup(void)
-{
- fstring server;
- char *p;
- struct in_addr *ip_list = NULL;
- int count = 0;
- int i;
-
- /* first off see if an existing workgroup name exists */
- p = smbw_getshared("WORKGROUP");
- if (!p) p = lp_workgroup();
-
- slprintf(server, sizeof(server), "%s#1D", p);
- if (smbw_server(server, "IPC$")) return p;
-
- /* go looking for workgroups */
- if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) {
- DEBUG(1,("No workgroups found!"));
- return p;
- }
-
- for (i=0;i<count;i++) {
- static fstring name;
- if (name_status_find("*", 0, 0x1d, ip_list[i], name)) {
- slprintf(server, sizeof(server), "%s#1D", name);
- if (smbw_server(server, "IPC$")) {
- smbw_setshared("WORKGROUP", name);
- SAFE_FREE(ip_list);
- return name;
- }
- }
- }
-
- SAFE_FREE(ip_list);
-
- return p;
-}
-
-/*****************************************************
-parse a smb path into its components.
-server is one of
- 1) the name of the SMB server
- 2) WORKGROUP#1D for share listing
- 3) WORKGROUP#__ for workgroup listing
-share is the share on the server to query
-path is the SMB path on the server
-return the full path (ie. add cwd if needed)
-*******************************************************/
-char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
-{
- static pstring s;
- char *p;
- int len;
- fstring workgroup;
-
- /* add cwd if necessary */
- if (fname[0] != '/') {
- slprintf(s, sizeof(s), "%s/%s", smbw_cwd, fname);
- } else {
- pstrcpy(s, fname);
- }
- clean_fname(s);
-
- /* see if it has the right prefix */
- len = strlen(smbw_prefix)-1;
- if (strncmp(s,smbw_prefix,len) ||
- (s[len] != '/' && s[len] != 0)) return s;
-
- /* ok, its for us. Now parse out the workgroup, share etc. */
- p = s+len;
- if (*p == '/') p++;
- if (!next_token(&p, workgroup, "/", sizeof(fstring))) {
- /* we're in /smb - give a list of workgroups */
- slprintf(server,sizeof(fstring), "%s#01", smbw_find_workgroup());
- fstrcpy(share,"IPC$");
- pstrcpy(path,"");
- return s;
- }
-
- if (!next_token(&p, server, "/", sizeof(fstring))) {
- /* we are in /smb/WORKGROUP */
- slprintf(server,sizeof(fstring), "%s#1D", workgroup);
- fstrcpy(share,"IPC$");
- pstrcpy(path,"");
- }
-
- if (!next_token(&p, share, "/", sizeof(fstring))) {
- /* we are in /smb/WORKGROUP/SERVER */
- fstrcpy(share,"IPC$");
- pstrcpy(path,"");
- }
-
- pstrcpy(path, p);
-
- all_string_sub(path, "/", "\\", 0);
-
- return s;
-}
-
-/*****************************************************
-determine if a path name (possibly relative) is in the
-smb name space
-*******************************************************/
-int smbw_path(const char *path)
-{
- fstring server, share;
- pstring s;
- char *cwd;
- int len;
-
- if(!path)
- return 0;
-
- /* this is needed to prevent recursion with the BSD malloc which
- opens /etc/malloc.conf on the first call */
- if (strncmp(path,"/etc/", 5) == 0) {
- return 0;
- }
-
- smbw_init();
-
- len = strlen(smbw_prefix)-1;
-
- if (path[0] == '/' && strncmp(path,smbw_prefix,len)) {
- return 0;
- }
-
- if (smbw_busy) return 0;
-
- DEBUG(3,("smbw_path(%s)\n", path));
-
- cwd = smbw_parse_path(path, server, share, s);
-
- if (strncmp(cwd,smbw_prefix,len) == 0 &&
- (cwd[len] == '/' || cwd[len] == 0)) {
- return 1;
- }
-
- return 0;
-}
-
-/*****************************************************
-return a unix errno from a SMB error pair
-*******************************************************/
-int smbw_errno(struct cli_state *c)
-{
- return cli_errno(c);
-}
-
-/* Return a username and password given a server and share name */
-
-void get_envvar_auth_data(char *server, char *share, char **workgroup,
- char **username, char **password)
-{
- /* Fall back to shared memory/environment variables */
-
- *username = smbw_getshared("USER");
- if (!*username) *username = getenv("USER");
- if (!*username) *username = "guest";
-
- *workgroup = smbw_getshared("WORKGROUP");
- if (!*workgroup) *workgroup = lp_workgroup();
-
- *password = smbw_getshared("PASSWORD");
- if (!*password) *password = "";
-}
-
-static smbw_get_auth_data_fn get_auth_data_fn = get_envvar_auth_data;
-
-/*****************************************************
-set the get auth data function
-******************************************************/
-void smbw_set_auth_data_fn(smbw_get_auth_data_fn fn)
-{
- get_auth_data_fn = fn;
-}
-
-/*****************************************************
-return a connection to a server (existing or new)
-*******************************************************/
-struct smbw_server *smbw_server(char *server, char *share)
-{
- struct smbw_server *srv=NULL;
- struct cli_state c;
- char *username;
- char *password;
- char *workgroup;
- struct nmb_name called, calling;
- char *p, *server_n = server;
- fstring group;
- pstring ipenv;
- struct in_addr ip;
-
- zero_ip(&ip);
- ZERO_STRUCT(c);
-
- get_auth_data_fn(server, share, &workgroup, &username, &password);
-
- /* try to use an existing connection */
- for (srv=smbw_srvs;srv;srv=srv->next) {
- if (strcmp(server,srv->server_name)==0 &&
- strcmp(share,srv->share_name)==0 &&
- strcmp(workgroup,srv->workgroup)==0 &&
- strcmp(username, srv->username) == 0)
- return srv;
- }
-
- if (server[0] == 0) {
- errno = EPERM;
- return NULL;
- }
-
- make_nmb_name(&calling, lp_netbios_name(), 0x0);
- make_nmb_name(&called , server, 0x20);
-
- DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server));
-
- if ((p=strchr_m(server_n,'#')) &&
- (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) {
- struct in_addr sip;
- pstring s;
-
- fstrcpy(group, server_n);
- p = strchr_m(group,'#');
- *p = 0;
-
- /* cache the workgroup master lookup */
- slprintf(s,sizeof(s)-1,"MASTER_%s", group);
- if (!(server_n = smbw_getshared(s))) {
- if (!find_master_ip(group, &sip)) {
- errno = ENOENT;
- return NULL;
- }
- fstrcpy(group, inet_ntoa(sip));
- server_n = group;
- smbw_setshared(s,server_n);
- }
- }
-
- DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
-
- again:
- slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
-
- zero_ip(&ip);
- if ((p=smbw_getshared(ipenv))) {
- ip = *(interpret_addr2(p));
- }
-
- /* have to open a new connection */
- if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) {
- errno = ENOENT;
- return NULL;
- }
-
- if (!cli_session_request(&c, &calling, &called)) {
- cli_shutdown(&c);
- if (strcmp(called.name, "*SMBSERVER")) {
- make_nmb_name(&called , "*SMBSERVER", 0x20);
- goto again;
- }
- errno = ENOENT;
- return NULL;
- }
-
- DEBUG(4,(" session request ok\n"));
-
- if (!cli_negprot(&c)) {
- cli_shutdown(&c);
- errno = ENOENT;
- return NULL;
- }
-
- if (!cli_session_setup(&c, username,
- password, strlen(password),
- password, strlen(password),
- workgroup) &&
- /* try an anonymous login if it failed */
- !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) {
- cli_shutdown(&c);
- errno = EPERM;
- return NULL;
- }
-
- DEBUG(4,(" session setup ok\n"));
-
- if (!cli_send_tconX(&c, share, "?????",
- password, strlen(password)+1)) {
- errno = smbw_errno(&c);
- cli_shutdown(&c);
- return NULL;
- }
-
- smbw_setshared(ipenv,inet_ntoa(ip));
-
- DEBUG(4,(" tconx ok\n"));
-
- srv = (struct smbw_server *)malloc(sizeof(*srv));
- if (!srv) {
- errno = ENOMEM;
- goto failed;
- }
-
- ZERO_STRUCTP(srv);
-
- srv->cli = c;
-
- srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
-
- srv->server_name = strdup(server);
- if (!srv->server_name) {
- errno = ENOMEM;
- goto failed;
- }
-
- srv->share_name = strdup(share);
- if (!srv->share_name) {
- errno = ENOMEM;
- goto failed;
- }
-
- srv->workgroup = strdup(workgroup);
- if (!srv->workgroup) {
- errno = ENOMEM;
- goto failed;
- }
-
- srv->username = strdup(username);
- if (!srv->username) {
- errno = ENOMEM;
- goto failed;
- }
-
- /* some programs play with file descriptors fairly intimately. We
- try to get out of the way by duping to a high fd number */
- if (fcntl(SMBW_CLI_FD + srv->cli.fd, F_GETFD) && errno == EBADF) {
- if (dup2(srv->cli.fd,SMBW_CLI_FD+srv->cli.fd) ==
- srv->cli.fd+SMBW_CLI_FD) {
- close(srv->cli.fd);
- srv->cli.fd += SMBW_CLI_FD;
- }
- }
-
- DLIST_ADD(smbw_srvs, srv);
-
- return srv;
-
- failed:
- cli_shutdown(&c);
- if (!srv) return NULL;
-
- SAFE_FREE(srv->server_name);
- SAFE_FREE(srv->share_name);
- SAFE_FREE(srv);
- return NULL;
-}
-
-
-/*****************************************************
-map a fd to a smbw_file structure
-*******************************************************/
-struct smbw_file *smbw_file(int fd)
-{
- struct smbw_file *file;
-
- for (file=smbw_files;file;file=file->next) {
- if (file->fd == fd) return file;
- }
- return NULL;
-}
-
-/*****************************************************
-a wrapper for open()
-*******************************************************/
-int smbw_open(const char *fname, int flags, mode_t mode)
-{
- fstring server, share;
- pstring path;
- struct smbw_server *srv=NULL;
- int eno=0, fd = -1;
- struct smbw_file *file=NULL;
-
- smbw_init();
-
- if (!fname) {
- errno = EINVAL;
- return -1;
- }
-
- smbw_busy++;
-
- /* work out what server they are after */
- smbw_parse_path(fname, server, share, path);
-
- /* get a connection to the server */
- srv = smbw_server(server, share);
- if (!srv) {
- /* smbw_server sets errno */
- goto failed;
- }
-
- if (path[strlen(path)-1] == '\\') {
- fd = -1;
- } else {
- fd = cli_open(&srv->cli, path, flags, DENY_NONE);
- }
- if (fd == -1) {
- /* it might be a directory. Maybe we should use chkpath? */
- eno = smbw_errno(&srv->cli);
- fd = smbw_dir_open(fname);
- if (fd == -1) errno = eno;
- smbw_busy--;
- return fd;
- }
-
- file = (struct smbw_file *)malloc(sizeof(*file));
- if (!file) {
- errno = ENOMEM;
- goto failed;
- }
-
- ZERO_STRUCTP(file);
-
- file->f = (struct smbw_filedes *)malloc(sizeof(*(file->f)));
- if (!file->f) {
- errno = ENOMEM;
- goto failed;
- }
-
- ZERO_STRUCTP(file->f);
-
- file->f->cli_fd = fd;
- file->f->fname = strdup(path);
- if (!file->f->fname) {
- errno = ENOMEM;
- goto failed;
- }
- file->srv = srv;
- file->fd = open(SMBW_DUMMY, O_WRONLY);
- if (file->fd == -1) {
- errno = EMFILE;
- goto failed;
- }
-
- if (bitmap_query(smbw_file_bmap, file->fd)) {
- DEBUG(0,("ERROR: fd used in smbw_open\n"));
- errno = EIO;
- goto failed;
- }
-
- file->f->ref_count=1;
-
- bitmap_set(smbw_file_bmap, file->fd);
-
- DLIST_ADD(smbw_files, file);
-
- DEBUG(4,("opened %s\n", fname));
-
- smbw_busy--;
- return file->fd;
-
- failed:
- if (fd != -1) {
- cli_close(&srv->cli, fd);
- }
- if (file) {
- if (file->f) {
- SAFE_FREE(file->f->fname);
- SAFE_FREE(file->f);
- }
- SAFE_FREE(file);
- }
- smbw_busy--;
- return -1;
-}
-
-
-/*****************************************************
-a wrapper for pread()
-*******************************************************/
-ssize_t smbw_pread(int fd, void *buf, size_t count, off_t ofs)
-{
- struct smbw_file *file;
- int ret;
-
- smbw_busy++;
-
- file = smbw_file(fd);
- if (!file) {
- errno = EBADF;
- smbw_busy--;
- return -1;
- }
-
- ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, ofs, count);
-
- if (ret == -1) {
- errno = smbw_errno(&file->srv->cli);
- smbw_busy--;
- return -1;
- }
-
- smbw_busy--;
- return ret;
-}
-
-/*****************************************************
-a wrapper for read()
-*******************************************************/
-ssize_t smbw_read(int fd, void *buf, size_t count)
-{
- struct smbw_file *file;
- int ret;
-
- DEBUG(4,("smbw_read(%d, %d)\n", fd, (int)count));
-
- smbw_busy++;
-
- file = smbw_file(fd);
- if (!file) {
- errno = EBADF;
- smbw_busy--;
- return -1;
- }
-
- ret = cli_read(&file->srv->cli, file->f->cli_fd, buf,
- file->f->offset, count);
-
- if (ret == -1) {
- errno = smbw_errno(&file->srv->cli);
- smbw_busy--;
- return -1;
- }
-
- file->f->offset += ret;
-
- DEBUG(4,(" -> %d\n", ret));
-
- smbw_busy--;
- return ret;
-}
-
-
-
-/*****************************************************
-a wrapper for write()
-*******************************************************/
-ssize_t smbw_write(int fd, void *buf, size_t count)
-{
- struct smbw_file *file;
- int ret;
-
- smbw_busy++;
-
- file = smbw_file(fd);
- if (!file) {
- errno = EBADF;
- smbw_busy--;
- return -1;
- }
-
- ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, file->f->offset, count);
-
- if (ret == -1) {
- errno = smbw_errno(&file->srv->cli);
- smbw_busy--;
- return -1;
- }
-
- file->f->offset += ret;
-
- smbw_busy--;
- return ret;
-}
-
-/*****************************************************
-a wrapper for pwrite()
-*******************************************************/
-ssize_t smbw_pwrite(int fd, void *buf, size_t count, off_t ofs)
-{
- struct smbw_file *file;
- int ret;
-
- smbw_busy++;
-
- file = smbw_file(fd);
- if (!file) {
- errno = EBADF;
- smbw_busy--;
- return -1;
- }
-
- ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, ofs, count);
-
- if (ret == -1) {
- errno = smbw_errno(&file->srv->cli);
- smbw_busy--;
- return -1;
- }
-
- smbw_busy--;
- return ret;
-}
-
-/*****************************************************
-a wrapper for close()
-*******************************************************/
-int smbw_close(int fd)
-{
- struct smbw_file *file;
-
- smbw_busy++;
-
- file = smbw_file(fd);
- if (!file) {
- int ret = smbw_dir_close(fd);
- smbw_busy--;
- return ret;
- }
-
- if (file->f->ref_count == 1 &&
- !cli_close(&file->srv->cli, file->f->cli_fd)) {
- errno = smbw_errno(&file->srv->cli);
- smbw_busy--;
- return -1;
- }
-
-
- bitmap_clear(smbw_file_bmap, file->fd);
- close(file->fd);
-
- DLIST_REMOVE(smbw_files, file);
-
- file->f->ref_count--;
- if (file->f->ref_count == 0) {
- SAFE_FREE(file->f->fname);
- SAFE_FREE(file->f);
- }
- ZERO_STRUCTP(file);
- SAFE_FREE(file);
-
- smbw_busy--;
-
- return 0;
-}
-
-
-/*****************************************************
-a wrapper for fcntl()
-*******************************************************/
-int smbw_fcntl(int fd, int cmd, long arg)
-{
- return 0;
-}
-
-
-/*****************************************************
-a wrapper for access()
-*******************************************************/
-int smbw_access(const char *name, int mode)
-{
- struct stat st;
-
- DEBUG(4,("smbw_access(%s, 0x%x)\n", name, mode));
-
- if (smbw_stat(name, &st)) return -1;
-
- if (((mode & R_OK) && !(st.st_mode & S_IRUSR)) ||
- ((mode & W_OK) && !(st.st_mode & S_IWUSR)) ||
- ((mode & X_OK) && !(st.st_mode & S_IXUSR))) {
- errno = EACCES;
- return -1;
- }
-
- return 0;
-}
-
-/*****************************************************
-a wrapper for realink() - needed for correct errno setting
-*******************************************************/
-int smbw_readlink(const char *path, char *buf, size_t bufsize)
-{
- struct stat st;
- int ret;
-
- ret = smbw_stat(path, &st);
- if (ret != 0) {
- DEBUG(4,("readlink(%s) failed\n", path));
- return -1;
- }
-
- /* it exists - say it isn't a link */
- DEBUG(4,("readlink(%s) not a link\n", path));
-
- errno = EINVAL;
- return -1;
-}
-
-
-/*****************************************************
-a wrapper for unlink()
-*******************************************************/
-int smbw_unlink(const char *fname)
-{
- struct smbw_server *srv;
- fstring server, share;
- pstring path;
-
- if (!fname) {
- errno = EINVAL;
- return -1;
- }
-
- smbw_init();
-
- smbw_busy++;
-
- /* work out what server they are after */
- smbw_parse_path(fname, server, share, path);
-
- /* get a connection to the server */
- srv = smbw_server(server, share);
- if (!srv) {
- /* smbw_server sets errno */
- goto failed;
- }
-
- if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
- int job = smbw_stat_printjob(srv, path, NULL, NULL);
- if (job == -1) {
- goto failed;
- }
- if (cli_printjob_del(&srv->cli, job) != 0) {
- goto failed;
- }
- } else if (!cli_unlink(&srv->cli, path)) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
-
- smbw_busy--;
- return 0;
-
- failed:
- smbw_busy--;
- return -1;
-}
-
-
-/*****************************************************
-a wrapper for rename()
-*******************************************************/
-int smbw_rename(const char *oldname, const char *newname)
-{
- struct smbw_server *srv;
- fstring server1, share1;
- pstring path1;
- fstring server2, share2;
- pstring path2;
-
- if (!oldname || !newname) {
- errno = EINVAL;
- return -1;
- }
-
- smbw_init();
-
- DEBUG(4,("smbw_rename(%s,%s)\n", oldname, newname));
-
- smbw_busy++;
-
- /* work out what server they are after */
- smbw_parse_path(oldname, server1, share1, path1);
- smbw_parse_path(newname, server2, share2, path2);
-
- if (strcmp(server1, server2) || strcmp(share1, share2)) {
- /* can't cross filesystems */
- errno = EXDEV;
- return -1;
- }
-
- /* get a connection to the server */
- srv = smbw_server(server1, share1);
- if (!srv) {
- /* smbw_server sets errno */
- goto failed;
- }
-
- if (!cli_rename(&srv->cli, path1, path2)) {
- int eno = smbw_errno(&srv->cli);
- if (eno != EEXIST ||
- !cli_unlink(&srv->cli, path2) ||
- !cli_rename(&srv->cli, path1, path2)) {
- errno = eno;
- goto failed;
- }
- }
-
- smbw_busy--;
- return 0;
-
- failed:
- smbw_busy--;
- return -1;
-}
-
-
-/*****************************************************
-a wrapper for utime and utimes
-*******************************************************/
-static int smbw_settime(const char *fname, time_t t)
-{
- struct smbw_server *srv;
- fstring server, share;
- pstring path;
- uint16 mode;
-
- if (!fname) {
- errno = EINVAL;
- return -1;
- }
-
- smbw_init();
-
- smbw_busy++;
-
- /* work out what server they are after */
- smbw_parse_path(fname, server, share, path);
-
- /* get a connection to the server */
- srv = smbw_server(server, share);
- if (!srv) {
- /* smbw_server sets errno */
- goto failed;
- }
-
- if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
-
- if (!cli_setatr(&srv->cli, path, mode, t)) {
- /* some servers always refuse directory changes */
- if (!(mode & aDIR)) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
- }
-
- smbw_busy--;
- return 0;
-
- failed:
- smbw_busy--;
- return -1;
-}
-
-/*****************************************************
-a wrapper for utime
-*******************************************************/
-int smbw_utime(const char *fname, void *buf)
-{
- struct utimbuf *tbuf = (struct utimbuf *)buf;
- return smbw_settime(fname, tbuf?tbuf->modtime:time(NULL));
-}
-
-/*****************************************************
-a wrapper for utime
-*******************************************************/
-int smbw_utimes(const char *fname, void *buf)
-{
- struct timeval *tbuf = (struct timeval *)buf;
- return smbw_settime(fname, tbuf?tbuf->tv_sec:time(NULL));
-}
-
-
-/*****************************************************
-a wrapper for chown()
-*******************************************************/
-int smbw_chown(const char *fname, uid_t owner, gid_t group)
-{
- struct smbw_server *srv;
- fstring server, share;
- pstring path;
- uint16 mode;
-
- if (!fname) {
- errno = EINVAL;
- return -1;
- }
-
- smbw_init();
-
- smbw_busy++;
-
- /* work out what server they are after */
- smbw_parse_path(fname, server, share, path);
-
- /* get a connection to the server */
- srv = smbw_server(server, share);
- if (!srv) {
- /* smbw_server sets errno */
- goto failed;
- }
-
- if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
-
- /* assume success */
-
- smbw_busy--;
- return 0;
-
- failed:
- smbw_busy--;
- return -1;
-}
-
-/*****************************************************
-a wrapper for chmod()
-*******************************************************/
-int smbw_chmod(const char *fname, mode_t newmode)
-{
- struct smbw_server *srv;
- fstring server, share;
- pstring path;
- uint32 mode;
-
- if (!fname) {
- errno = EINVAL;
- return -1;
- }
-
- smbw_init();
-
- smbw_busy++;
-
- /* work out what server they are after */
- smbw_parse_path(fname, server, share, path);
-
- /* get a connection to the server */
- srv = smbw_server(server, share);
- if (!srv) {
- /* smbw_server sets errno */
- goto failed;
- }
-
- mode = 0;
-
- if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY;
- if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH;
- if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
- if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
-
- if (!cli_setatr(&srv->cli, path, mode, 0)) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
-
- smbw_busy--;
- return 0;
-
- failed:
- smbw_busy--;
- return -1;
-}
-
-/*****************************************************
-a wrapper for lseek()
-*******************************************************/
-off_t smbw_lseek(int fd, off_t offset, int whence)
-{
- struct smbw_file *file;
- size_t size;
-
- smbw_busy++;
-
- file = smbw_file(fd);
- if (!file) {
- off_t ret = smbw_dir_lseek(fd, offset, whence);
- smbw_busy--;
- return ret;
- }
-
- switch (whence) {
- case SEEK_SET:
- file->f->offset = offset;
- break;
- case SEEK_CUR:
- file->f->offset += offset;
- break;
- case SEEK_END:
- if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd,
- NULL, &size, NULL, NULL, NULL,
- NULL, NULL) &&
- !cli_getattrE(&file->srv->cli, file->f->cli_fd,
- NULL, &size, NULL, NULL, NULL)) {
- errno = EINVAL;
- smbw_busy--;
- return -1;
- }
- file->f->offset = size + offset;
- break;
- }
-
- smbw_busy--;
- return file->f->offset;
-}
-
-
-/*****************************************************
-a wrapper for dup()
-*******************************************************/
-int smbw_dup(int fd)
-{
- int fd2;
- struct smbw_file *file, *file2;
-
- smbw_busy++;
-
- file = smbw_file(fd);
- if (!file) {
- errno = EBADF;
- goto failed;
- }
-
- fd2 = dup(file->fd);
- if (fd2 == -1) {
- goto failed;
- }
-
- if (bitmap_query(smbw_file_bmap, fd2)) {
- DEBUG(0,("ERROR: fd already open in dup!\n"));
- errno = EIO;
- goto failed;
- }
-
- file2 = (struct smbw_file *)malloc(sizeof(*file2));
- if (!file2) {
- close(fd2);
- errno = ENOMEM;
- goto failed;
- }
-
- ZERO_STRUCTP(file2);
-
- *file2 = *file;
- file2->fd = fd2;
-
- file->f->ref_count++;
-
- bitmap_set(smbw_file_bmap, fd2);
-
- DLIST_ADD(smbw_files, file2);
-
- smbw_busy--;
- return fd2;
-
- failed:
- smbw_busy--;
- return -1;
-}
-
-
-/*****************************************************
-a wrapper for dup2()
-*******************************************************/
-int smbw_dup2(int fd, int fd2)
-{
- struct smbw_file *file, *file2;
-
- smbw_busy++;
-
- file = smbw_file(fd);
- if (!file) {
- errno = EBADF;
- goto failed;
- }
-
- if (bitmap_query(smbw_file_bmap, fd2)) {
- DEBUG(0,("ERROR: fd already open in dup2!\n"));
- errno = EIO;
- goto failed;
- }
-
- if (dup2(file->fd, fd2) != fd2) {
- goto failed;
- }
-
- file2 = (struct smbw_file *)malloc(sizeof(*file2));
- if (!file2) {
- close(fd2);
- errno = ENOMEM;
- goto failed;
- }
-
- ZERO_STRUCTP(file2);
-
- *file2 = *file;
- file2->fd = fd2;
-
- file->f->ref_count++;
-
- bitmap_set(smbw_file_bmap, fd2);
-
- DLIST_ADD(smbw_files, file2);
-
- smbw_busy--;
- return fd2;
-
- failed:
- smbw_busy--;
- return -1;
-}
-
-
-/*****************************************************
-close a connection to a server
-*******************************************************/
-static void smbw_srv_close(struct smbw_server *srv)
-{
- smbw_busy++;
-
- cli_shutdown(&srv->cli);
-
- SAFE_FREE(srv->server_name);
- SAFE_FREE(srv->share_name);
-
- DLIST_REMOVE(smbw_srvs, srv);
-
- ZERO_STRUCTP(srv);
-
- SAFE_FREE(srv);
-
- smbw_busy--;
-}
-
-/*****************************************************
-when we fork we have to close all connections and files
-in the child
-*******************************************************/
-int smbw_fork(void)
-{
- pid_t child;
- int p[2];
- char c=0;
- pstring line;
-
- struct smbw_file *file, *next_file;
- struct smbw_server *srv, *next_srv;
-
- if (pipe(p)) return real_fork();
-
- child = real_fork();
-
- if (child) {
- /* block the parent for a moment until the sockets are
- closed */
- close(p[1]);
- read(p[0], &c, 1);
- close(p[0]);
- return child;
- }
-
- close(p[0]);
-
- /* close all files */
- for (file=smbw_files;file;file=next_file) {
- next_file = file->next;
- close(file->fd);
- }
-
- /* close all server connections */
- for (srv=smbw_srvs;srv;srv=next_srv) {
- next_srv = srv->next;
- smbw_srv_close(srv);
- }
-
- slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
- smbw_setshared(line,smbw_cwd);
-
- /* unblock the parent */
- write(p[1], &c, 1);
- close(p[1]);
-
- /* and continue in the child */
- return 0;
-}
-
-#ifndef NO_ACL_WRAPPER
-/*****************************************************
-say no to acls
-*******************************************************/
- int smbw_acl(const char *pathp, int cmd, int nentries, aclent_t *aclbufp)
-{
- if (cmd == GETACL || cmd == GETACLCNT) return 0;
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef NO_FACL_WRAPPER
-/*****************************************************
-say no to acls
-*******************************************************/
- int smbw_facl(int fd, int cmd, int nentries, aclent_t *aclbufp)
-{
- if (cmd == GETACL || cmd == GETACLCNT) return 0;
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifdef HAVE_EXPLICIT_LARGEFILE_SUPPORT
-#ifdef HAVE_STAT64
-/* this can't be in wrapped.c because of include conflicts */
- void stat64_convert(struct stat *st, struct stat64 *st64)
-{
- st64->st_size = st->st_size;
- st64->st_mode = st->st_mode;
- st64->st_ino = st->st_ino;
- st64->st_dev = st->st_dev;
- st64->st_rdev = st->st_rdev;
- st64->st_nlink = st->st_nlink;
- st64->st_uid = st->st_uid;
- st64->st_gid = st->st_gid;
- st64->st_atime = st->st_atime;
- st64->st_mtime = st->st_mtime;
- st64->st_ctime = st->st_ctime;
- st64->st_blksize = st->st_blksize;
- st64->st_blocks = st->st_blocks;
-}
-#endif
-
-#ifdef HAVE_READDIR64
- void dirent64_convert(struct dirent *d, struct dirent64 *d64)
-{
- d64->d_ino = d->d_ino;
- d64->d_off = d->d_off;
- d64->d_reclen = d->d_reclen;
- pstrcpy(d64->d_name, d->d_name);
-}
-#endif
-#endif
-
-
-#ifdef HAVE___XSTAT
-/* Definition of `struct stat' used in the linux kernel.. */
-struct kernel_stat {
- unsigned short int st_dev;
- unsigned short int __pad1;
- unsigned long int st_ino;
- unsigned short int st_mode;
- unsigned short int st_nlink;
- unsigned short int st_uid;
- unsigned short int st_gid;
- unsigned short int st_rdev;
- unsigned short int __pad2;
- unsigned long int st_size;
- unsigned long int st_blksize;
- unsigned long int st_blocks;
- unsigned long int st_atime;
- unsigned long int __unused1;
- unsigned long int st_mtime;
- unsigned long int __unused2;
- unsigned long int st_ctime;
- unsigned long int __unused3;
- unsigned long int __unused4;
- unsigned long int __unused5;
-};
-
-/*
- * Prototype for gcc in 'fussy' mode.
- */
- void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf);
- void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf)
-{
-#ifdef _STAT_VER_LINUX_OLD
- if (vers == _STAT_VER_LINUX_OLD) {
- memcpy(st, kbuf, sizeof(*st));
- return;
- }
-#endif
-
- ZERO_STRUCTP(st);
-
- st->st_dev = kbuf->st_dev;
- st->st_ino = kbuf->st_ino;
- st->st_mode = kbuf->st_mode;
- st->st_nlink = kbuf->st_nlink;
- st->st_uid = kbuf->st_uid;
- st->st_gid = kbuf->st_gid;
- st->st_rdev = kbuf->st_rdev;
- st->st_size = kbuf->st_size;
- st->st_blksize = kbuf->st_blksize;
- st->st_blocks = kbuf->st_blocks;
- st->st_atime = kbuf->st_atime;
- st->st_mtime = kbuf->st_mtime;
- st->st_ctime = kbuf->st_ctime;
-}
-#endif
diff --git a/source4/smbwrapper/smbw.h b/source4/smbwrapper/smbw.h
deleted file mode 100644
index 3f0b1cbb44..0000000000
--- a/source4/smbwrapper/smbw.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB wrapper functions - definitions
- Copyright (C) Andrew Tridgell 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.
-*/
-
-#ifndef _SMBW_H
-#define _SMBW_H
-
-#define SMBW_PREFIX "/smb/"
-#define SMBW_DUMMY "/dev/null"
-
-#define SMBW_CLI_FD 512
-#define SMBW_MAX_OPEN 8192
-
-#define SMBW_FILE_MODE (S_IFREG | 0444)
-#define SMBW_DIR_MODE (S_IFDIR | 0555)
-
-struct smbw_server {
- struct smbw_server *next, *prev;
- struct cli_state cli;
- char *server_name;
- char *share_name;
- char *workgroup;
- char *username;
- dev_t dev;
- BOOL no_pathinfo2;
-};
-
-struct smbw_filedes {
- int cli_fd;
- int ref_count;
- char *fname;
- off_t offset;
-};
-
-struct smbw_file {
- struct smbw_file *next, *prev;
- struct smbw_filedes *f;
- int fd;
- struct smbw_server *srv;
-};
-
-struct smbw_dir {
- struct smbw_dir *next, *prev;
- int fd;
- int offset, count, malloced;
- struct smbw_server *srv;
- struct file_info *list;
- char *path;
-};
-
-typedef void (*smbw_get_auth_data_fn)(char *server, char *share,
- char **workgroup, char **username,
- char **password);
-
-#endif /* _SMBW_H */
diff --git a/source4/smbwrapper/smbw_cache.c b/source4/smbwrapper/smbw_cache.c
deleted file mode 100644
index fcb0eda805..0000000000
--- a/source4/smbwrapper/smbw_cache.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB wrapper directory functions
- Copyright (C) Tim Potter 2000
-
- 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"
-
-/* We cache lists of workgroups, lists of servers in workgroups, and lists
- of shares exported by servers. */
-
-#define CACHE_TIMEOUT 30
-
-struct name_list {
- struct name_list *prev, *next;
- char *name;
- uint32 stype;
- char *comment;
-};
-
-struct cached_names {
- struct cached_names *prev, *next;
- char *key;
- struct name_list *name_list;
- time_t cache_timeout;
- int result;
-};
-
-static struct cached_names *cached_names = NULL;
-
-/* Find a list of cached name for a workgroup, server or share list */
-
-static struct cached_names *find_cached_names(char *key)
-{
- struct cached_names *tmp;
-
- for (tmp = cached_names; tmp; tmp = tmp->next) {
- if (strequal(tmp->key, key)) {
- return tmp;
- }
- }
-
- return NULL;
-}
-
-/* Add a name to a list stored in the state variable */
-
-static void add_cached_names(const char *name, uint32 stype,
- const char *comment, void *state)
-{
- struct name_list **name_list = (struct name_list **)state;
- struct name_list *new_name;
-
- new_name = (struct name_list *)malloc(sizeof(struct name_list));
- if (!new_name) return;
-
- ZERO_STRUCTP(new_name);
-
- new_name->name = strdup(name);
- new_name->stype = stype;
- new_name->comment = strdup(comment);
-
- DLIST_ADD(*name_list, new_name);
-}
-
-static void free_name_list(struct name_list *name_list)
-{
- struct name_list *tmp = name_list;
-
- while(tmp) {
- struct name_list *next;
-
- next = tmp->next;
-
- SAFE_FREE(tmp->name);
- SAFE_FREE(tmp->comment);
- SAFE_FREE(tmp);
-
- tmp = next;
- }
-}
-
-/* Wrapper for NetServerEnum function */
-
-BOOL smbw_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
- void (*fn)(const char *, uint32, const char *, void *),
- void *state)
-{
- struct cached_names *names;
- struct name_list *tmp;
- time_t now = time(NULL);
- char key[PATH_MAX];
- BOOL result = True;
-
- slprintf(key, PATH_MAX - 1, "%s/%s#%s", cli->desthost,
- workgroup, (stype == SV_TYPE_DOMAIN_ENUM ? "DOM" : "SRV"));
-
- names = find_cached_names(key);
-
- if (names == NULL || (now - names->cache_timeout) > CACHE_TIMEOUT) {
- struct cached_names *new_names = NULL;
-
- /* No names cached for this workgroup */
-
- if (names == NULL) {
- new_names = (struct cached_names *)
- malloc(sizeof(struct cached_names));
-
- ZERO_STRUCTP(new_names);
- DLIST_ADD(cached_names, new_names);
-
- } else {
-
- /* Dispose of out of date name list */
-
- free_name_list(names->name_list);
- names->name_list = NULL;
-
- new_names = names;
- }
-
- result = cli_NetServerEnum(cli, workgroup, stype,
- add_cached_names,
- &new_names->name_list);
-
- new_names->cache_timeout = now;
- new_names->result = result;
- new_names->key = strdup(key);
-
- names = new_names;
- }
-
- /* Return names by running callback function. */
-
- for (tmp = names->name_list; tmp; tmp = tmp->next)
- fn(tmp->name, stype, tmp->comment, state);
-
- return names->result;
-}
-
-/* Wrapper for RNetShareEnum function */
-
-int smbw_RNetShareEnum(struct cli_state *cli,
- void (*fn)(const char *, uint32, const char *, void *),
- void *state)
-{
- struct cached_names *names;
- struct name_list *tmp;
- time_t now = time(NULL);
- char key[PATH_MAX];
-
- slprintf(key, PATH_MAX - 1, "SHARE/%s", cli->desthost);
-
- names = find_cached_names(key);
-
- if (names == NULL || (now - names->cache_timeout) > CACHE_TIMEOUT) {
- struct cached_names *new_names = NULL;
-
- /* No names cached for this server */
-
- if (names == NULL) {
- new_names = (struct cached_names *)
- malloc(sizeof(struct cached_names));
-
- ZERO_STRUCTP(new_names);
- DLIST_ADD(cached_names, new_names);
-
- } else {
-
- /* Dispose of out of date name list */
-
- free_name_list(names->name_list);
- names->name_list = NULL;
-
- new_names = names;
- }
-
- new_names->result = cli_RNetShareEnum(cli, add_cached_names,
- &new_names->name_list);
-
- new_names->cache_timeout = now;
- new_names->key = strdup(key);
-
- names = new_names;
- }
-
- /* Return names by running callback function. */
-
- for (tmp = names->name_list; tmp; tmp = tmp->next)
- fn(tmp->name, tmp->stype, tmp->comment, state);
-
- return names->result;
-}
diff --git a/source4/smbwrapper/smbw_dir.c b/source4/smbwrapper/smbw_dir.c
deleted file mode 100644
index 31d81a1e7e..0000000000
--- a/source4/smbwrapper/smbw_dir.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB wrapper directory functions
- Copyright (C) Andrew Tridgell 1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "realcalls.h"
-
-extern pstring smbw_cwd;
-extern fstring smbw_prefix;
-
-static struct smbw_dir *smbw_dirs;
-
-extern struct bitmap *smbw_file_bmap;
-
-extern int smbw_busy;
-
-/*****************************************************
-map a fd to a smbw_dir structure
-*******************************************************/
-struct smbw_dir *smbw_dir(int fd)
-{
- struct smbw_dir *dir;
-
- for (dir=smbw_dirs;dir;dir=dir->next) {
- if (dir->fd == fd) return dir;
- }
- return NULL;
-}
-
-/*****************************************************
-check if a DIR* is one of ours
-*******************************************************/
-int smbw_dirp(DIR *dirp)
-{
- struct smbw_dir *d = (struct smbw_dir *)dirp;
- struct smbw_dir *dir;
-
- for (dir=smbw_dirs;dir;dir=dir->next) {
- if (dir == d) return 1;
- }
- return 0;
-}
-
-/*****************************************************
-free a smbw_dir structure and all entries
-*******************************************************/
-static void free_dir(struct smbw_dir *dir)
-{
- if(!dir) return;
-
- SAFE_FREE(dir->list);
- SAFE_FREE(dir->path);
- ZERO_STRUCTP(dir);
- SAFE_FREE(dir);
-}
-
-static struct smbw_dir *cur_dir;
-
-/*****************************************************
-add a entry to a directory listing
-*******************************************************/
-static void smbw_dir_add(struct file_info *finfo, const char *mask,
- void *state)
-{
- struct file_info *cdl;
-
- DEBUG(5,("%s\n", finfo->name));
-
- if (cur_dir->malloced == cur_dir->count) {
- cdl = (struct file_info *)Realloc(cur_dir->list,
- sizeof(cur_dir->list[0])*
- (cur_dir->count+100));
- if (!cdl) {
- /* oops */
- return;
- }
- cur_dir->list = cdl;
- cur_dir->malloced += 100;
- }
-
- cur_dir->list[cur_dir->count] = *finfo;
- cur_dir->count++;
-}
-
-/*****************************************************
-add a entry to a directory listing
-*******************************************************/
-static void smbw_share_add(const char *share, uint32 type,
- const char *comment, void *state)
-{
- struct file_info finfo;
-
- if (strcmp(share,"IPC$") == 0) return;
-
- ZERO_STRUCT(finfo);
-
- pstrcpy(finfo.name, share);
- finfo.mode = aRONLY | aDIR;
-
- smbw_dir_add(&finfo, NULL, NULL);
-}
-
-
-/*****************************************************
-add a server to a directory listing
-*******************************************************/
-static void smbw_server_add(const char *name, uint32 type,
- const char *comment, void *state)
-{
- struct file_info finfo;
-
- ZERO_STRUCT(finfo);
-
- pstrcpy(finfo.name, name);
- finfo.mode = aRONLY | aDIR;
-
- smbw_dir_add(&finfo, NULL, NULL);
-}
-
-
-/*****************************************************
-add a entry to a directory listing
-*******************************************************/
-static void smbw_printjob_add(struct print_job_info *job)
-{
- struct file_info finfo;
-
- ZERO_STRUCT(finfo);
-
- pstrcpy(finfo.name, job->name);
- finfo.mode = aRONLY | aDIR;
- finfo.mtime = job->t;
- finfo.atime = job->t;
- finfo.ctime = job->t;
- finfo.uid = nametouid(job->user);
- finfo.mode = aRONLY;
- finfo.size = job->size;
-
- smbw_dir_add(&finfo, NULL, NULL);
-}
-
-
-/*****************************************************
-open a directory on the server
-*******************************************************/
-int smbw_dir_open(const char *fname)
-{
- fstring server, share;
- pstring path;
- struct smbw_server *srv=NULL;
- struct smbw_dir *dir=NULL;
- pstring mask;
- int fd;
- char *s, *p;
-
- if (!fname) {
- errno = EINVAL;
- return -1;
- }
-
- smbw_init();
-
- /* work out what server they are after */
- s = smbw_parse_path(fname, server, share, path);
-
- DEBUG(4,("dir_open share=%s\n", share));
-
- /* get a connection to the server */
- srv = smbw_server(server, share);
- if (!srv) {
- /* smbw_server sets errno */
- goto failed;
- }
-
- dir = (struct smbw_dir *)malloc(sizeof(*dir));
- if (!dir) {
- errno = ENOMEM;
- goto failed;
- }
-
- ZERO_STRUCTP(dir);
-
- cur_dir = dir;
-
- slprintf(mask, sizeof(mask)-1, "%s\\*", path);
- all_string_sub(mask,"\\\\","\\",0);
-
- if ((p=strstr(srv->server_name,"#01"))) {
- *p = 0;
- smbw_server_add(".",0,"", NULL);
- smbw_server_add("..",0,"", NULL);
- smbw_NetServerEnum(&srv->cli, srv->server_name,
- SV_TYPE_DOMAIN_ENUM, smbw_server_add, NULL);
- *p = '#';
- } else if ((p=strstr(srv->server_name,"#1D"))) {
- DEBUG(4,("doing NetServerEnum\n"));
- *p = 0;
- smbw_server_add(".",0,"", NULL);
- smbw_server_add("..",0,"", NULL);
- smbw_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_ALL,
- smbw_server_add, NULL);
- *p = '#';
- } else if (strcmp(srv->cli.dev,"IPC") == 0) {
- DEBUG(4,("doing NetShareEnum\n"));
- smbw_share_add(".",0,"", NULL);
- smbw_share_add("..",0,"", NULL);
- if (smbw_RNetShareEnum(&srv->cli, smbw_share_add, NULL) < 0) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
- } else if (strncmp(srv->cli.dev,"LPT",3) == 0) {
- smbw_share_add(".",0,"", NULL);
- smbw_share_add("..",0,"", NULL);
- if (cli_print_queue(&srv->cli, smbw_printjob_add) < 0) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
- } else {
-#if 0
- if (strcmp(path,"\\") == 0) {
- smbw_share_add(".",0,"");
- smbw_share_add("..",0,"");
- }
-#endif
- if (cli_list(&srv->cli, mask, aHIDDEN|aSYSTEM|aDIR,
- smbw_dir_add, NULL) < 0) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
- }
-
- cur_dir = NULL;
-
- fd = open(SMBW_DUMMY, O_WRONLY);
- if (fd == -1) {
- errno = EMFILE;
- goto failed;
- }
-
- if (bitmap_query(smbw_file_bmap, fd)) {
- DEBUG(0,("ERROR: fd used in smbw_dir_open\n"));
- errno = EIO;
- goto failed;
- }
-
- DLIST_ADD(smbw_dirs, dir);
-
- bitmap_set(smbw_file_bmap, fd);
-
- dir->fd = fd;
- dir->srv = srv;
- dir->path = strdup(s);
-
- DEBUG(4,(" -> %d\n", dir->count));
-
- return dir->fd;
-
- failed:
- free_dir(dir);
-
- return -1;
-}
-
-/*****************************************************
-a wrapper for fstat() on a directory
-*******************************************************/
-int smbw_dir_fstat(int fd, struct stat *st)
-{
- struct smbw_dir *dir;
-
- dir = smbw_dir(fd);
- if (!dir) {
- errno = EBADF;
- return -1;
- }
-
- ZERO_STRUCTP(st);
-
- smbw_setup_stat(st, "", dir->count*DIRP_SIZE, aDIR);
-
- st->st_dev = dir->srv->dev;
-
- return 0;
-}
-
-/*****************************************************
-close a directory handle
-*******************************************************/
-int smbw_dir_close(int fd)
-{
- struct smbw_dir *dir;
-
- dir = smbw_dir(fd);
- if (!dir) {
- errno = EBADF;
- return -1;
- }
-
- bitmap_clear(smbw_file_bmap, dir->fd);
- close(dir->fd);
-
- DLIST_REMOVE(smbw_dirs, dir);
-
- free_dir(dir);
-
- return 0;
-}
-
-/*****************************************************
-a wrapper for getdents()
-*******************************************************/
-int smbw_getdents(unsigned int fd, struct dirent *dirp, int count)
-{
- struct smbw_dir *dir;
- int n=0;
-
- smbw_busy++;
-
- dir = smbw_dir(fd);
- if (!dir) {
- errno = EBADF;
- smbw_busy--;
- return -1;
- }
-
- while (count>=DIRP_SIZE && (dir->offset < dir->count)) {
-#if HAVE_DIRENT_D_OFF
- dirp->d_off = (dir->offset+1)*DIRP_SIZE;
-#endif
- dirp->d_reclen = DIRP_SIZE;
- fstrcpy(&dirp->d_name[0], dir->list[dir->offset].name);
- dirp->d_ino = smbw_inode(dir->list[dir->offset].name);
- dir->offset++;
- count -= dirp->d_reclen;
-#if HAVE_DIRENT_D_OFF
- if (dir->offset == dir->count) {
- dirp->d_off = -1;
- }
-#endif
- dirp = (struct dirent *)(((char *)dirp) + DIRP_SIZE);
- n++;
- }
-
- smbw_busy--;
- return n*DIRP_SIZE;
-}
-
-
-/*****************************************************
-a wrapper for chdir()
-*******************************************************/
-int smbw_chdir(const char *name)
-{
- struct smbw_server *srv;
- fstring server, share;
- pstring path;
- uint16 mode = aDIR;
- char *cwd;
- int len;
-
- smbw_init();
-
- len = strlen(smbw_prefix);
-
- if (smbw_busy) return real_chdir(name);
-
- smbw_busy++;
-
- if (!name) {
- errno = EINVAL;
- goto failed;
- }
-
- DEBUG(4,("smbw_chdir(%s)\n", name));
-
- /* work out what server they are after */
- cwd = smbw_parse_path(name, server, share, path);
-
- /* a special case - accept cd to /smb */
- if (strncmp(cwd, smbw_prefix, len-1) == 0 &&
- cwd[len-1] == 0) {
- goto success1;
- }
-
- if (strncmp(cwd,smbw_prefix,strlen(smbw_prefix))) {
- if (real_chdir(cwd) == 0) {
- goto success2;
- }
- goto failed;
- }
-
- /* get a connection to the server */
- srv = smbw_server(server, share);
- if (!srv) {
- /* smbw_server sets errno */
- goto failed;
- }
-
- if (strncmp(srv->cli.dev,"IPC",3) &&
- strncmp(srv->cli.dev,"LPT",3) &&
- !smbw_getatr(srv, path,
- &mode, NULL, NULL, NULL, NULL, NULL)) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
-
- if (!(mode & aDIR)) {
- errno = ENOTDIR;
- goto failed;
- }
-
- success1:
- /* we don't want the old directory to be busy */
- real_chdir("/");
-
- success2:
-
- DEBUG(4,("set SMBW_CWD to %s\n", cwd));
-
- pstrcpy(smbw_cwd, cwd);
-
- smbw_busy--;
- return 0;
-
- failed:
- smbw_busy--;
- return -1;
-}
-
-
-/*****************************************************
-a wrapper for lseek() on directories
-*******************************************************/
-off_t smbw_dir_lseek(int fd, off_t offset, int whence)
-{
- struct smbw_dir *dir;
- off_t ret;
-
- dir = smbw_dir(fd);
- if (!dir) {
- errno = EBADF;
- return -1;
- }
-
- switch (whence) {
- case SEEK_SET:
- dir->offset = offset/DIRP_SIZE;
- break;
- case SEEK_CUR:
- dir->offset += offset/DIRP_SIZE;
- break;
- case SEEK_END:
- dir->offset = (dir->count * DIRP_SIZE) + offset;
- dir->offset /= DIRP_SIZE;
- break;
- }
-
- ret = dir->offset * DIRP_SIZE;
-
- DEBUG(4,(" -> %d\n", (int)ret));
-
- return ret;
-}
-
-
-/*****************************************************
-a wrapper for mkdir()
-*******************************************************/
-int smbw_mkdir(const char *fname, mode_t mode)
-{
- struct smbw_server *srv;
- fstring server, share;
- pstring path;
-
- if (!fname) {
- errno = EINVAL;
- return -1;
- }
-
- smbw_init();
-
- smbw_busy++;
-
- /* work out what server they are after */
- smbw_parse_path(fname, server, share, path);
-
- /* get a connection to the server */
- srv = smbw_server(server, share);
- if (!srv) {
- /* smbw_server sets errno */
- goto failed;
- }
-
- if (!cli_mkdir(&srv->cli, path)) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
-
- smbw_busy--;
- return 0;
-
- failed:
- smbw_busy--;
- return -1;
-}
-
-/*****************************************************
-a wrapper for rmdir()
-*******************************************************/
-int smbw_rmdir(const char *fname)
-{
- struct smbw_server *srv;
- fstring server, share;
- pstring path;
-
- if (!fname) {
- errno = EINVAL;
- return -1;
- }
-
- smbw_init();
-
- smbw_busy++;
-
- /* work out what server they are after */
- smbw_parse_path(fname, server, share, path);
-
- /* get a connection to the server */
- srv = smbw_server(server, share);
- if (!srv) {
- /* smbw_server sets errno */
- goto failed;
- }
-
- if (!cli_rmdir(&srv->cli, path)) {
- errno = smbw_errno(&srv->cli);
- goto failed;
- }
-
- smbw_busy--;
- return 0;
-
- failed:
- smbw_busy--;
- return -1;
-}
-
-
-/*****************************************************
-a wrapper for getcwd()
-*******************************************************/
-char *smbw_getcwd(char *buf, size_t size)
-{
- smbw_init();
-
- if (smbw_busy) {
- return (char *)real_getcwd(buf, size);
- }
-
- smbw_busy++;
-
- if (!buf) {
- if (size <= 0) size = strlen(smbw_cwd)+1;
- buf = (char *)malloc(size);
- if (!buf) {
- errno = ENOMEM;
- smbw_busy--;
- return NULL;
- }
- }
-
- if (strlen(smbw_cwd) > size-1) {
- errno = ERANGE;
- smbw_busy--;
- return NULL;
- }
-
- safe_strcpy(buf, smbw_cwd, size);
-
- smbw_busy--;
- return buf;
-}
-
-/*****************************************************
-a wrapper for fchdir()
-*******************************************************/
-int smbw_fchdir(unsigned int fd)
-{
- struct smbw_dir *dir;
- int ret;
-
- smbw_busy++;
-
- dir = smbw_dir(fd);
- if (dir) {
- smbw_busy--;
- return chdir(dir->path);
- }
-
- ret = real_fchdir(fd);
- if (ret == 0) {
- sys_getwd(smbw_cwd);
- }
-
- smbw_busy--;
- return ret;
-}
-
-/*****************************************************
-open a directory on the server
-*******************************************************/
-DIR *smbw_opendir(const char *fname)
-{
- int fd;
-
- smbw_busy++;
-
- fd = smbw_dir_open(fname);
-
- if (fd == -1) {
- smbw_busy--;
- return NULL;
- }
-
- smbw_busy--;
-
- return (DIR *)smbw_dir(fd);
-}
-
-/*****************************************************
-read one entry from a directory
-*******************************************************/
-struct dirent *smbw_readdir(DIR *dirp)
-{
- struct smbw_dir *d = (struct smbw_dir *)dirp;
- static union {
- char buf[DIRP_SIZE];
- struct dirent de;
- } dbuf;
-
- if (smbw_getdents(d->fd, &dbuf.de, DIRP_SIZE) > 0)
- return &dbuf.de;
-
- return NULL;
-}
-
-/*****************************************************
-close a DIR*
-*******************************************************/
-int smbw_closedir(DIR *dirp)
-{
- struct smbw_dir *d = (struct smbw_dir *)dirp;
- return smbw_close(d->fd);
-}
-
-/*****************************************************
-seek in a directory
-*******************************************************/
-void smbw_seekdir(DIR *dirp, off_t offset)
-{
- struct smbw_dir *d = (struct smbw_dir *)dirp;
- smbw_dir_lseek(d->fd,offset, SEEK_SET);
-}
-
-/*****************************************************
-current loc in a directory
-*******************************************************/
-off_t smbw_telldir(DIR *dirp)
-{
- struct smbw_dir *d = (struct smbw_dir *)dirp;
- return smbw_dir_lseek(d->fd,0,SEEK_CUR);
-}
diff --git a/source4/smbwrapper/smbw_stat.c b/source4/smbwrapper/smbw_stat.c
deleted file mode 100644
index 6c476a8a67..0000000000
--- a/source4/smbwrapper/smbw_stat.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB wrapper stat functions
- Copyright (C) Andrew Tridgell 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"
-
-extern int smbw_busy;
-
-/*****************************************************
-setup basic info in a stat structure
-*******************************************************/
-void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode)
-{
- st->st_mode = 0;
-
- if (IS_DOS_DIR(mode)) {
- st->st_mode = SMBW_DIR_MODE;
- } else {
- st->st_mode = SMBW_FILE_MODE;
- }
-
- if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR;
- if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP;
- if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH;
- if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
-
- st->st_size = size;
- st->st_blksize = 512;
- st->st_blocks = (size+511)/512;
- st->st_uid = getuid();
- st->st_gid = getgid();
- if (IS_DOS_DIR(mode)) {
- st->st_nlink = 2;
- } else {
- st->st_nlink = 1;
- }
- if (st->st_ino == 0) {
- st->st_ino = smbw_inode(fname);
- }
-}
-
-
-/*****************************************************
-try to do a QPATHINFO and if that fails then do a getatr
-this is needed because win95 sometimes refuses the qpathinfo
-*******************************************************/
-BOOL smbw_getatr(struct smbw_server *srv, char *path,
- uint16 *mode, size_t *size,
- time_t *c_time, time_t *a_time, time_t *m_time,
- SMB_INO_T *ino)
-{
- DEBUG(4,("sending qpathinfo\n"));
-
- if (!srv->no_pathinfo2 &&
- cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL,
- size, mode, ino)) return True;
-
- /* if this is NT then don't bother with the getatr */
- if (srv->cli.capabilities & CAP_NT_SMBS) return False;
-
- if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
- a_time = c_time = m_time;
- srv->no_pathinfo2 = True;
- return True;
- }
- return False;
-}
-
-
-static struct print_job_info printjob;
-
-/*****************************************************
-gather info from a printjob listing
-*******************************************************/
-static void smbw_printjob_stat(struct print_job_info *job)
-{
- if (strcmp(job->name, printjob.name) == 0) {
- printjob = *job;
- }
-}
-
-/*****************************************************
-stat a printjob
-*******************************************************/
-int smbw_stat_printjob(struct smbw_server *srv,char *path,
- size_t *size, time_t *m_time)
-{
- if (path[0] == '\\') path++;
-
- ZERO_STRUCT(printjob);
-
- fstrcpy(printjob.name, path);
- cli_print_queue(&srv->cli, smbw_printjob_stat);
-
- if (size) {
- *size = printjob.size;
- }
- if (m_time) {
- *m_time = printjob.t;
- }
- return printjob.id;
-}
-
-
-/*****************************************************
-a wrapper for fstat()
-*******************************************************/
-int smbw_fstat(int fd, struct stat *st)
-{
- struct smbw_file *file;
- time_t c_time, a_time, m_time;
- size_t size;
- uint16 mode;
- SMB_INO_T ino = 0;
-
- smbw_busy++;
-
- ZERO_STRUCTP(st);
-
- file = smbw_file(fd);
- if (!file) {
- int ret = smbw_dir_fstat(fd, st);
- smbw_busy--;
- return ret;
- }
-
- if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd,
- &mode, &size, &c_time, &a_time, &m_time, NULL,
- &ino) &&
- !cli_getattrE(&file->srv->cli, file->f->cli_fd,
- &mode, &size, &c_time, &a_time, &m_time)) {
- errno = EINVAL;
- smbw_busy--;
- return -1;
- }
-
- st->st_ino = ino;
-
- smbw_setup_stat(st, file->f->fname, size, mode);
-
- st->st_atime = a_time;
- st->st_ctime = c_time;
- st->st_mtime = m_time;
- st->st_dev = file->srv->dev;
-
- smbw_busy--;
- return 0;
-}
-
-
-/*****************************************************
-a wrapper for stat()
-*******************************************************/
-int smbw_stat(const char *fname, struct stat *st)
-{
- struct smbw_server *srv;
- fstring server, share;
- pstring path;
- time_t m_time=0, a_time=0, c_time=0;
- size_t size=0;
- uint16 mode=0;
- SMB_INO_T ino = 0;
- int result = 0;
-
- ZERO_STRUCTP(st);
-
- if (!fname) {
- errno = EINVAL;
- return -1;
- }
-
- DEBUG(4,("stat(%s)\n", fname));
-
- smbw_init();
-
- smbw_busy++;
-
- /* work out what server they are after */
- smbw_parse_path(fname, server, share, path);
-
- /* get a connection to the server */
- srv = smbw_server(server, share);
- if (!srv) {
-
- /* For shares we aren't allowed to connect to, or no master
- browser found, return an empty directory */
-
- if ((server[0] && share[0] && !path[0] && errno == EACCES) ||
- (!path[0] && errno == ENOENT)) {
- mode = aDIR | aRONLY;
- smbw_setup_stat(st, path, size, mode);
- goto done;
- }
-
- /* smbw_server sets errno */
- result = -1;
- goto done;
- }
-
- DEBUG(4,("smbw_stat\n"));
-
- if (strncmp(srv->cli.dev,"IPC",3) == 0) {
- mode = aDIR | aRONLY;
- } else if (strncmp(srv->cli.dev,"LPT",3) == 0) {
- if (strcmp(path,"\\") == 0) {
- mode = aDIR | aRONLY;
- } else {
- mode = aRONLY;
- smbw_stat_printjob(srv, path, &size, &m_time);
- c_time = a_time = m_time;
- }
- } else {
- if (!smbw_getatr(srv, path,
- &mode, &size, &c_time, &a_time, &m_time,
- &ino)) {
- errno = smbw_errno(&srv->cli);
- result = -1;
- goto done;
- }
- }
-
- st->st_ino = ino;
-
- smbw_setup_stat(st, path, size, mode);
-
- st->st_atime = a_time;
- st->st_ctime = c_time;
- st->st_mtime = m_time;
- st->st_dev = srv->dev;
-
- done:
- smbw_busy--;
- return result;
-}
diff --git a/source4/smbwrapper/wrapped.c b/source4/smbwrapper/wrapped.c
deleted file mode 100644
index 338ee0d5b1..0000000000
--- a/source4/smbwrapper/wrapped.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB wrapper functions
- Copyright (C) Andrew Tridgell 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.
-*/
-
-/* NOTE: This file WILL produce compiler warnings. They are unavoidable
-
- Do not try and get rid of them by including other include files or
- by including includes.h or proto.h or you will break portability.
- */
-
-#include "config.h"
-#include <sys/types.h>
-#include <errno.h>
-#include "realcalls.h"
-
-#ifndef NULL
-# define NULL ((void *)0)
-#endif
-
- int open(char *name, int flags, mode_t mode)
-{
- if (smbw_path(name)) {
- return smbw_open(name, flags, mode);
- }
-
- return real_open(name, flags, mode);
-}
-
-#ifdef HAVE__OPEN
- int _open(char *name, int flags, mode_t mode)
-{
- return open(name, flags, mode);
-}
-#elif HAVE___OPEN
- int __open(char *name, int flags, mode_t mode)
-{
- return open(name, flags, mode);
-}
-#endif
-
-
-#ifdef HAVE_OPEN64
- int open64(char *name, int flags, mode_t mode)
-{
- if (smbw_path(name)) {
- return smbw_open(name, flags, mode);
- }
-
- return real_open64(name, flags, mode);
-}
-#endif
-
-#ifndef NO_OPEN64_ALIAS
-#ifdef HAVE__OPEN64
- int _open64(char *name, int flags, mode_t mode)
-{
- return open64(name, flags, mode);
-}
-#elif HAVE___OPEN64
- int __open64(char *name, int flags, mode_t mode)
-{
- return open64(name, flags, mode);
-}
-#endif
-#endif
-
-#ifdef HAVE_PREAD
- ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
-{
- if (smbw_fd(fd)) {
- return smbw_pread(fd, buf, size, ofs);
- }
-
- return real_pread(fd, buf, size, ofs);
-}
-#endif
-
-#if defined(HAVE_PREAD64) && defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT)
- ssize_t pread64(int fd, void *buf, size_t size, off64_t ofs)
-{
- if (smbw_fd(fd)) {
- return smbw_pread(fd, buf, size, ofs);
- }
-
- return real_pread64(fd, buf, size, ofs);
-}
-#endif
-
-#ifdef HAVE_PWRITE
- ssize_t pwrite(int fd, void *buf, size_t size, off_t ofs)
-{
- if (smbw_fd(fd)) {
- return smbw_pwrite(fd, buf, size, ofs);
- }
-
- return real_pwrite(fd, buf, size, ofs);
-}
-#endif
-
-#if defined(HAVE_PWRITE64) && defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT)
- ssize_t pwrite64(int fd, void *buf, size_t size, off64_t ofs)
-{
- if (smbw_fd(fd)) {
- return smbw_pwrite(fd, buf, size, ofs);
- }
-
- return real_pwrite64(fd, buf, size, ofs);
-}
-#endif
-
-
- int chdir(char *name)
-{
- return smbw_chdir(name);
-}
-
-#ifdef HAVE___CHDIR
- int __chdir(char *name)
-{
- return chdir(name);
-}
-#elif HAVE__CHDIR
- int _chdir(char *name)
-{
- return chdir(name);
-}
-#endif
-
-
- int close(int fd)
-{
- if (smbw_fd(fd)) {
- return smbw_close(fd);
- }
- if (smbw_local_fd(fd)) {
- errno = EBADF;
- return -1;
- }
-
- return real_close(fd);
-}
-
-#ifdef HAVE___CLOSE
- int __close(int fd)
-{
- return close(fd);
-}
-#elif HAVE__CLOSE
- int _close(int fd)
-{
- return close(fd);
-}
-#endif
-
-
- int fchdir(int fd)
-{
- return smbw_fchdir(fd);
-}
-
-#ifdef HAVE___FCHDIR
- int __fchdir(int fd)
-{
- return fchdir(fd);
-}
-#elif HAVE__FCHDIR
- int _fchdir(int fd)
-{
- return fchdir(fd);
-}
-#endif
-
-
- int fcntl(int fd, int cmd, long arg)
-{
- if (smbw_fd(fd)) {
- return smbw_fcntl(fd, cmd, arg);
- }
-
- return real_fcntl(fd, cmd, arg);
-}
-
-
-#ifdef HAVE___FCNTL
- int __fcntl(int fd, int cmd, long arg)
-{
- return fcntl(fd, cmd, arg);
-}
-#elif HAVE__FCNTL
- int _fcntl(int fd, int cmd, long arg)
-{
- return fcntl(fd, cmd, arg);
-}
-#endif
-
-
-
-#ifdef real_getdents
- int getdents(int fd, void *dirp, unsigned int count)
-{
- if (smbw_fd(fd)) {
- return smbw_getdents(fd, dirp, count);
- }
-
- return real_getdents(fd, dirp, count);
-}
-#endif
-
-#ifdef HAVE___GETDENTS
- int __getdents(int fd, void *dirp, unsigned int count)
-{
- return getdents(fd, dirp, count);
-}
-#elif HAVE__GETDENTS
- int _getdents(int fd, void *dirp, unsigned int count)
-{
- return getdents(fd, dirp, count);
-}
-#endif
-
-
- off_t lseek(int fd, off_t offset, int whence)
-{
- if (smbw_fd(fd)) {
- return smbw_lseek(fd, offset, whence);
- }
-
- return real_lseek(fd, offset, whence);
-}
-
-#ifdef HAVE___LSEEK
- off_t __lseek(int fd, off_t offset, int whence)
-{
- return lseek(fd, offset, whence);
-}
-#elif HAVE__LSEEK
- off_t _lseek(int fd, off_t offset, int whence)
-{
- return lseek(fd, offset, whence);
-}
-#endif
-
-
- ssize_t read(int fd, void *buf, size_t count)
-{
- if (smbw_fd(fd)) {
- return smbw_read(fd, buf, count);
- }
-
- return real_read(fd, buf, count);
-}
-
-#ifdef HAVE___READ
- ssize_t __read(int fd, void *buf, size_t count)
-{
- return read(fd, buf, count);
-}
-#elif HAVE__READ
- ssize_t _read(int fd, void *buf, size_t count)
-{
- return read(fd, buf, count);
-}
-#endif
-
-
- ssize_t write(int fd, void *buf, size_t count)
-{
- if (smbw_fd(fd)) {
- return smbw_write(fd, buf, count);
- }
-
- return real_write(fd, buf, count);
-}
-
-#ifdef HAVE___WRITE
- ssize_t __write(int fd, void *buf, size_t count)
-{
- return write(fd, buf, count);
-}
-#elif HAVE__WRITE
- ssize_t _write(int fd, void *buf, size_t count)
-{
- return write(fd, buf, count);
-}
-#endif
-
-
-
- int access(char *name, int mode)
-{
- if (smbw_path(name)) {
- return smbw_access(name, mode);
- }
-
- return real_access(name, mode);
-}
-
-
-
- int chmod(char *name,mode_t mode)
-{
- if (smbw_path(name)) {
- return smbw_chmod(name, mode);
- }
-
- return real_chmod(name, mode);
-}
-
-
-
- int chown(char *name,uid_t owner, gid_t group)
-{
- if (smbw_path(name)) {
- return smbw_chown(name, owner, group);
- }
-
- return real_chown(name, owner, group);
-}
-
-
- char *getcwd(char *buf, size_t size)
-{
- return (char *)smbw_getcwd(buf, size);
-}
-
-
-
-
- int mkdir(char *name, mode_t mode)
-{
- if (smbw_path(name)) {
- return smbw_mkdir(name, mode);
- }
-
- return real_mkdir(name, mode);
-}
-
-
-#if HAVE___FXSTAT
- int __fxstat(int vers, int fd, void *st)
-{
- double xx[32];
- int ret;
-
- if (smbw_fd(fd)) {
- return smbw_fstat(fd, st);
- }
-
- ret = real_fstat(fd, xx);
- xstat_convert(vers, st, xx);
- return ret;
-}
-#endif
-
-#if HAVE___XSTAT
- int __xstat(int vers, char *name, void *st)
-{
- double xx[32];
- int ret;
-
- if (smbw_path(name)) {
- return smbw_stat(name, st);
- }
-
- ret = real_stat(name, xx);
- xstat_convert(vers, st, xx);
- return ret;
-}
-#endif
-
-
-#if HAVE___LXSTAT
- int __lxstat(int vers, char *name, void *st)
-{
- double xx[32];
- int ret;
-
- if (smbw_path(name)) {
- return smbw_stat(name, st);
- }
-
- ret = real_lstat(name, xx);
- xstat_convert(vers, st, xx);
- return ret;
-}
-#endif
-
-
- int stat(char *name, void *st)
-{
-#if HAVE___XSTAT
- return __xstat(0, name, st);
-#else
- if (smbw_path(name)) {
- return smbw_stat(name, st);
- }
- return real_stat(name, st);
-#endif
-}
-
- int lstat(char *name, void *st)
-{
-#if HAVE___LXSTAT
- return __lxstat(0, name, st);
-#else
- if (smbw_path(name)) {
- return smbw_stat(name, st);
- }
- return real_lstat(name, st);
-#endif
-}
-
- int fstat(int fd, void *st)
-{
-#if HAVE___LXSTAT
- return __fxstat(0, fd, st);
-#else
- if (smbw_fd(fd)) {
- return smbw_fstat(fd, st);
- }
- return real_fstat(fd, st);
-#endif
-}
-
-
- int unlink(char *name)
-{
- if (smbw_path(name)) {
- return smbw_unlink(name);
- }
-
- return real_unlink(name);
-}
-
-
-#ifdef HAVE_UTIME
- int utime(char *name,void *tvp)
-{
- if (smbw_path(name)) {
- return smbw_utime(name, tvp);
- }
-
- return real_utime(name, tvp);
-}
-#endif
-
-#ifdef HAVE_UTIMES
- int utimes(const char *name, const struct timeval *tvp)
-{
- if (smbw_path(name)) {
- return smbw_utimes(name, tvp);
- }
-
- return real_utimes(name, tvp);
-}
-#endif
-
- int readlink(char *path, char *buf, size_t bufsize)
-{
- if (smbw_path(path)) {
- return smbw_readlink(path, buf, bufsize);
- }
-
- return real_readlink(path, buf, bufsize);
-}
-
-
- int rename(char *oldname,char *newname)
-{
- int p1, p2;
- p1 = smbw_path(oldname);
- p2 = smbw_path(newname);
- if (p1 ^ p2) {
- /* can't cross filesystem boundaries */
- errno = EXDEV;
- return -1;
- }
- if (p1 && p2) {
- return smbw_rename(oldname, newname);
- }
-
- return real_rename(oldname, newname);
-}
-
- int rmdir(char *name)
-{
- if (smbw_path(name)) {
- return smbw_rmdir(name);
- }
-
- return real_rmdir(name);
-}
-
-
- int symlink(char *topath,char *frompath)
-{
- int p1, p2;
- p1 = smbw_path(topath);
- p2 = smbw_path(frompath);
- if (p1 || p2) {
- /* can't handle symlinks */
- errno = EPERM;
- return -1;
- }
-
- return real_symlink(topath, frompath);
-}
-
- int dup(int fd)
-{
- if (smbw_fd(fd)) {
- return smbw_dup(fd);
- }
-
- return real_dup(fd);
-}
-
- int dup2(int oldfd, int newfd)
-{
- if (smbw_fd(newfd)) {
- close(newfd);
- }
-
- if (smbw_fd(oldfd)) {
- return smbw_dup2(oldfd, newfd);
- }
-
- return real_dup2(oldfd, newfd);
-}
-
-#ifdef real_opendir
- void *opendir(char *name)
-{
- if (smbw_path(name)) {
- return (void *)smbw_opendir(name);
- }
-
- return (void *)real_opendir(name);
-}
-#endif
-
-#ifdef real_readdir
- void *readdir(void *dir)
-{
- if (smbw_dirp(dir)) {
- return (void *)smbw_readdir(dir);
- }
-
- return (void *)real_readdir(dir);
-}
-#endif
-
-#ifdef real_closedir
- int closedir(void *dir)
-{
- if (smbw_dirp(dir)) {
- return smbw_closedir(dir);
- }
-
- return real_closedir(dir);
-}
-#endif
-
-#ifdef real_telldir
- off_t telldir(void *dir)
-{
- if (smbw_dirp(dir)) {
- return smbw_telldir(dir);
- }
-
- return real_telldir(dir);
-}
-#endif
-
-#ifdef real_seekdir
- int seekdir(void *dir, off_t offset)
-{
- if (smbw_dirp(dir)) {
- smbw_seekdir(dir, offset);
- return 0;
- }
-
- real_seekdir(dir, offset);
- return 0;
-}
-#endif
-
-
-#ifndef NO_ACL_WRAPPER
- int acl(char *pathp, int cmd, int nentries, void *aclbufp)
-{
- if (smbw_path(pathp)) {
- return smbw_acl(pathp, cmd, nentries, aclbufp);
- }
-
- return real_acl(pathp, cmd, nentries, aclbufp);
-}
-#endif
-
-#ifndef NO_FACL_WRAPPER
- int facl(int fd, int cmd, int nentries, void *aclbufp)
-{
- if (smbw_fd(fd)) {
- return smbw_facl(fd, cmd, nentries, aclbufp);
- }
-
- return real_facl(fd, cmd, nentries, aclbufp);
-}
-#endif
-
- int creat(char *path, mode_t mode)
-{
- extern int creat_bits;
- return open(path, creat_bits, mode);
-}
-
-#ifdef HAVE_CREAT64
- int creat64(char *path, mode_t mode)
-{
- extern int creat_bits;
- return open64(path, creat_bits, mode);
-}
-#endif
-
-#ifdef HAVE_STAT64
- int stat64(char *name, void *st64)
-{
- if (smbw_path(name)) {
- double xx[32];
- int ret = stat(name, xx);
- stat64_convert(xx, st64);
- return ret;
- }
- return real_stat64(name, st64);
-}
-
- int fstat64(int fd, void *st64)
-{
- if (smbw_fd(fd)) {
- double xx[32];
- int ret = fstat(fd, xx);
- stat64_convert(xx, st64);
- return ret;
- }
- return real_fstat64(fd, st64);
-}
-
- int lstat64(char *name, void *st64)
-{
- if (smbw_path(name)) {
- double xx[32];
- int ret = lstat(name, xx);
- stat64_convert(xx, st64);
- return ret;
- }
- return real_lstat64(name, st64);
-}
-#endif
-
-#ifdef HAVE_LLSEEK
- offset_t llseek(int fd, offset_t ofs, int whence)
-{
- if (smbw_fd(fd)) {
- return lseek(fd, ofs, whence);
- }
- return real_llseek(fd, ofs, whence);
-}
-#endif
-
-#ifdef HAVE_READDIR64
- void *readdir64(void *dir)
-{
- if (smbw_dirp(dir)) {
- static double xx[70];
- void *d;
- d = (void *)readdir(dir);
- if (!d) return NULL;
- dirent64_convert(d, xx);
- return xx;
- }
- return (void *)real_readdir64(dir);
-}
-#endif
-
- int fork(void)
-{
- return smbw_fork();
-}
-
diff --git a/source4/web/cgi.c b/source4/web/cgi.c
deleted file mode 100644
index f755bb22e9..0000000000
--- a/source4/web/cgi.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- some simple CGI helper routines
- Copyright (C) Andrew Tridgell 1997-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"
-
-#define MAX_VARIABLES 10000
-
-/* set the expiry on fixed pages */
-#define EXPIRY_TIME (60*60*24*7)
-
-#ifdef DEBUG_COMMENTS
-extern void print_title(char *fmt, ...);
-#endif
-
-struct var {
- char *name;
- char *value;
-};
-
-static struct var variables[MAX_VARIABLES];
-static int num_variables;
-static int content_length;
-static int request_post;
-static char *query_string;
-static const char *baseurl;
-static char *pathinfo;
-static char *C_user;
-static BOOL inetd_server;
-static BOOL got_request;
-
-static char *grab_line(FILE *f, int *cl)
-{
- char *ret = NULL;
- int i = 0;
- int len = 0;
-
- while ((*cl)) {
- int c;
-
- if (i == len) {
- char *ret2;
- if (len == 0) len = 1024;
- else len *= 2;
- ret2 = (char *)Realloc(ret, len);
- if (!ret2) return ret;
- ret = ret2;
- }
-
- c = fgetc(f);
- (*cl)--;
-
- if (c == EOF) {
- (*cl) = 0;
- break;
- }
-
- if (c == '\r') continue;
-
- if (strchr_m("\n&", c)) break;
-
- ret[i++] = c;
-
- }
-
-
- ret[i] = 0;
- return ret;
-}
-
-/***************************************************************************
- load all the variables passed to the CGI program. May have multiple variables
- with the same name and the same or different values. Takes a file parameter
- for simulating CGI invocation eg loading saved preferences.
- ***************************************************************************/
-void cgi_load_variables(void)
-{
- static char *line;
- char *p, *s, *tok;
- int len, i;
- FILE *f = stdin;
-
-#ifdef DEBUG_COMMENTS
- char dummy[100]="";
- print_title(dummy);
- d_printf("<!== Start dump in cgi_load_variables() %s ==>\n",__FILE__);
-#endif
-
- if (!content_length) {
- p = getenv("CONTENT_LENGTH");
- len = p?atoi(p):0;
- } else {
- len = content_length;
- }
-
-
- if (len > 0 &&
- (request_post ||
- ((s=getenv("REQUEST_METHOD")) &&
- strcasecmp(s,"POST")==0))) {
- while (len && (line=grab_line(f, &len))) {
- p = strchr_m(line,'=');
- if (!p) continue;
-
- *p = 0;
-
- variables[num_variables].name = strdup(line);
- variables[num_variables].value = strdup(p+1);
-
- SAFE_FREE(line);
-
- if (!variables[num_variables].name ||
- !variables[num_variables].value)
- continue;
-
- rfc1738_unescape(variables[num_variables].value);
- rfc1738_unescape(variables[num_variables].name);
-
-#ifdef DEBUG_COMMENTS
- printf("<!== POST var %s has value \"%s\" ==>\n",
- variables[num_variables].name,
- variables[num_variables].value);
-#endif
-
- num_variables++;
- if (num_variables == MAX_VARIABLES) break;
- }
- }
-
- fclose(stdin);
- open("/dev/null", O_RDWR);
-
- if ((s=query_string) || (s=getenv("QUERY_STRING"))) {
- for (tok=strtok(s,"&;");tok;tok=strtok(NULL,"&;")) {
- p = strchr_m(tok,'=');
- if (!p) continue;
-
- *p = 0;
-
- variables[num_variables].name = strdup(tok);
- variables[num_variables].value = strdup(p+1);
-
- if (!variables[num_variables].name ||
- !variables[num_variables].value)
- continue;
-
- rfc1738_unescape(variables[num_variables].value);
- rfc1738_unescape(variables[num_variables].name);
-
-#ifdef DEBUG_COMMENTS
- printf("<!== Commandline var %s has value \"%s\" ==>\n",
- variables[num_variables].name,
- variables[num_variables].value);
-#endif
- num_variables++;
- if (num_variables == MAX_VARIABLES) break;
- }
-
- }
-#ifdef DEBUG_COMMENTS
- printf("<!== End dump in cgi_load_variables() ==>\n");
-#endif
-
- /* variables from the client are in display charset - convert them
- to our internal charset before use */
- for (i=0;i<num_variables;i++) {
- pstring dest;
-
- convert_string(CH_DISPLAY, CH_UNIX,
- variables[i].name, -1,
- dest, sizeof(dest));
- free(variables[i].name);
- variables[i].name = strdup(dest);
-
- convert_string(CH_DISPLAY, CH_UNIX,
- variables[i].value, -1,
- dest, sizeof(dest));
- free(variables[i].value);
- variables[i].value = strdup(dest);
- }
-}
-
-
-/***************************************************************************
- find a variable passed via CGI
- Doesn't quite do what you think in the case of POST text variables, because
- if they exist they might have a value of "" or even " ", depending on the
- browser. Also doesn't allow for variables[] containing multiple variables
- with the same name and the same or different values.
- ***************************************************************************/
-const char *cgi_variable(const char *name)
-{
- int i;
-
- for (i=0;i<num_variables;i++)
- if (strcmp(variables[i].name, name) == 0)
- return variables[i].value;
- return NULL;
-}
-
-/***************************************************************************
-tell a browser about a fatal error in the http processing
- ***************************************************************************/
-static void cgi_setup_error(const char *err, const char *header, const char *info)
-{
- if (!got_request) {
- /* damn browsers don't like getting cut off before they give a request */
- char line[1024];
- while (fgets(line, sizeof(line)-1, stdin)) {
- if (strncasecmp(line,"GET ", 4)==0 ||
- strncasecmp(line,"POST ", 5)==0 ||
- strncasecmp(line,"PUT ", 4)==0) {
- break;
- }
- }
- }
-
- d_printf("HTTP/1.0 %s\r\n%sConnection: close\r\nContent-Type: text/html\r\n\r\n<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><H1>%s</H1>%s<p></BODY></HTML>\r\n\r\n", err, header, err, err, info);
- fclose(stdin);
- fclose(stdout);
- exit(0);
-}
-
-
-/***************************************************************************
-tell a browser about a fatal authentication error
- ***************************************************************************/
-static void cgi_auth_error(void)
-{
- if (inetd_server) {
- cgi_setup_error("401 Authorization Required",
- "WWW-Authenticate: Basic realm=\"SWAT\"\r\n",
- "You must be authenticated to use this service");
- } else {
- printf("Content-Type: text/html\r\n");
-
- printf("\r\n<HTML><HEAD><TITLE>SWAT</TITLE></HEAD>\n");
- printf("<BODY><H1>Installation Error</H1>\n");
- printf("SWAT must be installed via inetd. It cannot be run as a CGI script<p>\n");
- printf("</BODY></HTML>\r\n");
- }
- exit(0);
-}
-
-/***************************************************************************
-authenticate when we are running as a CGI
- ***************************************************************************/
-static void cgi_web_auth(void)
-{
- const char *user = getenv("REMOTE_USER");
- struct passwd *pwd;
- const char *head = "Content-Type: text/html\r\n\r\n<HTML><BODY><H1>SWAT installation Error</H1>\n";
- const char *tail = "</BODY></HTML>\r\n";
-
- if (!user) {
- printf("%sREMOTE_USER not set. Not authenticated by web server.<br>%s\n",
- head, tail);
- exit(0);
- }
-
- pwd = getpwnam_alloc(user);
- if (!pwd) {
- printf("%sCannot find user %s<br>%s\n", head, user, tail);
- exit(0);
- }
-
- setuid(0);
- setuid(pwd->pw_uid);
- if (geteuid() != pwd->pw_uid || getuid() != pwd->pw_uid) {
- printf("%sFailed to become user %s - uid=%d/%d<br>%s\n",
- head, user, (int)geteuid(), (int)getuid(), tail);
- exit(0);
- }
- passwd_free(&pwd);
-}
-
-
-/***************************************************************************
-handle a http authentication line
- ***************************************************************************/
-static BOOL cgi_handle_authorization(char *line)
-{
- char *p;
- fstring user, user_pass;
- struct passwd *pass = NULL;
-
- if (strncasecmp(line,"Basic ", 6)) {
- goto err;
- }
- line += 6;
- while (line[0] == ' ') line++;
- base64_decode_inplace(line);
- if (!(p=strchr_m(line,':'))) {
- /*
- * Always give the same error so a cracker
- * cannot tell why we fail.
- */
- goto err;
- }
- *p = 0;
-
- convert_string(CH_DISPLAY, CH_UNIX,
- line, -1,
- user, sizeof(user));
-
- convert_string(CH_DISPLAY, CH_UNIX,
- p+1, -1,
- user_pass, sizeof(user_pass));
-
- /*
- * Try and get the user from the UNIX password file.
- */
-
- pass = getpwnam_alloc(user);
-
- /*
- * Validate the password they have given.
- */
-
- if NT_STATUS_IS_OK(pass_check(pass, user, user_pass,
- strlen(user_pass), NULL, False)) {
-
- if (pass) {
- /*
- * Password was ok.
- */
-
- become_user_permanently(pass->pw_uid, pass->pw_gid);
-
- /* Save the users name */
- C_user = strdup(user);
- passwd_free(&pass);
- return True;
- }
- }
-
-err:
- cgi_setup_error("401 Bad Authorization", "",
- "username or password incorrect");
-
- passwd_free(&pass);
- return False;
-}
-
-/***************************************************************************
-is this root?
- ***************************************************************************/
-BOOL am_root(void)
-{
- if (geteuid() == 0) {
- return( True);
- } else {
- return( False);
- }
-}
-
-/***************************************************************************
-return a ptr to the users name
- ***************************************************************************/
-char *cgi_user_name(void)
-{
- return(C_user);
-}
-
-
-/***************************************************************************
-handle a file download
- ***************************************************************************/
-static void cgi_download(char *file)
-{
- SMB_STRUCT_STAT st;
- char buf[1024];
- int fd, l, i;
- char *p;
- char *lang;
-
- /* sanitise the filename */
- for (i=0;file[i];i++) {
- if (!isalnum((int)file[i]) && !strchr_m("/.-_", file[i])) {
- cgi_setup_error("404 File Not Found","",
- "Illegal character in filename");
- }
- }
-
- if (!file_exist(file, &st)) {
- cgi_setup_error("404 File Not Found","",
- "The requested file was not found");
- }
-
- fd = web_open(file,O_RDONLY,0);
- if (fd == -1) {
- cgi_setup_error("404 File Not Found","",
- "The requested file was not found");
- }
- printf("HTTP/1.0 200 OK\r\n");
- if ((p=strrchr_m(file,'.'))) {
- if (strcmp(p,".gif")==0) {
- printf("Content-Type: image/gif\r\n");
- } else if (strcmp(p,".jpg")==0) {
- printf("Content-Type: image/jpeg\r\n");
- } else if (strcmp(p,".txt")==0) {
- printf("Content-Type: text/plain\r\n");
- } else {
- printf("Content-Type: text/html\r\n");
- }
- }
- printf("Expires: %s\r\n", http_timestring(time(NULL)+EXPIRY_TIME));
-
- lang = lang_tdb_current();
- if (lang) {
- printf("Content-Language: %s\r\n", lang);
- }
-
- printf("Content-Length: %d\r\n\r\n", (int)st.st_size);
- while ((l=read(fd,buf,sizeof(buf)))>0) {
- fwrite(buf, 1, l, stdout);
- }
- close(fd);
- exit(0);
-}
-
-
-
-
-/**
- * @brief Setup the CGI framework.
- *
- * Setup the cgi framework, handling the possibility that this program
- * is either run as a true CGI program with a gateway to a web server, or
- * is itself a mini web server.
- **/
-void cgi_setup(const char *rootdir, int auth_required)
-{
- BOOL authenticated = False;
- char line[1024];
- char *url=NULL;
- char *p;
- char *lang;
-
- if (chdir(rootdir)) {
- cgi_setup_error("500 Server Error", "",
- "chdir failed - the server is not configured correctly");
- }
-
- /* Handle the possibility we might be running as non-root */
- sec_init();
-
- if ((lang=getenv("HTTP_ACCEPT_LANGUAGE"))) {
- /* if running as a cgi program */
- web_set_lang(lang);
- }
-
- /* maybe we are running under a web server */
- if (getenv("CONTENT_LENGTH") || getenv("REQUEST_METHOD")) {
- if (auth_required) {
- cgi_web_auth();
- }
- return;
- }
-
- inetd_server = True;
-
- if (!check_access(1, lp_hostsallow(-1), lp_hostsdeny(-1))) {
- cgi_setup_error("403 Forbidden", "",
- "Samba is configured to deny access from this client\n<br>Check your \"hosts allow\" and \"hosts deny\" options in smb.conf ");
- }
-
- /* we are a mini-web server. We need to read the request from stdin
- and handle authentication etc */
- while (fgets(line, sizeof(line)-1, stdin)) {
- if (line[0] == '\r' || line[0] == '\n') break;
- if (strncasecmp(line,"GET ", 4)==0) {
- got_request = True;
- url = strdup(&line[4]);
- } else if (strncasecmp(line,"POST ", 5)==0) {
- got_request = True;
- request_post = 1;
- url = strdup(&line[5]);
- } else if (strncasecmp(line,"PUT ", 4)==0) {
- got_request = True;
- cgi_setup_error("400 Bad Request", "",
- "This server does not accept PUT requests");
- } else if (strncasecmp(line,"Authorization: ", 15)==0) {
- authenticated = cgi_handle_authorization(&line[15]);
- } else if (strncasecmp(line,"Content-Length: ", 16)==0) {
- content_length = atoi(&line[16]);
- } else if (strncasecmp(line,"Accept-Language: ", 17)==0) {
- web_set_lang(&line[17]);
- }
- /* ignore all other requests! */
- }
-
- if (auth_required && !authenticated) {
- cgi_auth_error();
- }
-
- if (!url) {
- cgi_setup_error("400 Bad Request", "",
- "You must specify a GET or POST request");
- }
-
- /* trim the URL */
- if ((p = strchr_m(url,' ')) || (p=strchr_m(url,'\t'))) {
- *p = 0;
- }
- while (*url && strchr_m("\r\n",url[strlen(url)-1])) {
- url[strlen(url)-1] = 0;
- }
-
- /* anything following a ? in the URL is part of the query string */
- if ((p=strchr_m(url,'?'))) {
- query_string = p+1;
- *p = 0;
- }
-
- string_sub(url, "/swat/", "", 0);
-
- if (url[0] != '/' && strstr(url,"..")==0 && file_exist(url, NULL)) {
- cgi_download(url);
- }
-
- printf("HTTP/1.0 200 OK\r\nConnection: close\r\n");
- printf("Date: %s\r\n", http_timestring(time(NULL)));
- baseurl = "";
- pathinfo = url+1;
-}
-
-
-/***************************************************************************
-return the current pages URL
- ***************************************************************************/
-const char *cgi_baseurl(void)
-{
- if (inetd_server) {
- return baseurl;
- }
- return getenv("SCRIPT_NAME");
-}
-
-/***************************************************************************
-return the current pages path info
- ***************************************************************************/
-const char *cgi_pathinfo(void)
-{
- char *r;
- if (inetd_server) {
- return pathinfo;
- }
- r = getenv("PATH_INFO");
- if (!r) return "";
- if (*r == '/') r++;
- return r;
-}
-
-/***************************************************************************
-return the hostname of the client
- ***************************************************************************/
-char *cgi_remote_host(void)
-{
- if (inetd_server) {
- return get_socket_name(1,False);
- }
- return getenv("REMOTE_HOST");
-}
-
-/***************************************************************************
-return the hostname of the client
- ***************************************************************************/
-char *cgi_remote_addr(void)
-{
- if (inetd_server) {
- return get_socket_addr(1);
- }
- return getenv("REMOTE_ADDR");
-}
-
-
-/***************************************************************************
-return True if the request was a POST
- ***************************************************************************/
-BOOL cgi_waspost(void)
-{
- if (inetd_server) {
- return request_post;
- }
- return strequal(getenv("REQUEST_METHOD"), "POST");
-}
diff --git a/source4/web/config.m4 b/source4/web/config.m4
deleted file mode 100644
index f8bb33759d..0000000000
--- a/source4/web/config.m4
+++ /dev/null
@@ -1,17 +0,0 @@
-#################################################
-# set SWAT directory location
-AC_ARG_WITH(swatdir,
-[ --with-swatdir=DIR Where to put SWAT files ($ac_default_prefix/swat)],
-[ case "$withval" in
- yes|no)
- #
- # Just in case anybody does it
- #
- AC_MSG_WARN([--with-swatdir called without argument - will use default])
- ;;
- * )
- swatdir="$withval"
- ;;
- esac])
-
-AC_SUBST(swatdir)
diff --git a/source4/web/diagnose.c b/source4/web/diagnose.c
deleted file mode 100644
index f79d59fc6a..0000000000
--- a/source4/web/diagnose.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- diagnosis tools for web admin
- Copyright (C) Andrew Tridgell 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_WINBIND
-
-NSS_STATUS winbindd_request(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response);
-
-/* check to see if winbind is running by pinging it */
-
-BOOL winbindd_running(void)
-{
-
- if (winbindd_request(WINBINDD_PING, NULL, NULL))
- return False;
-
- return True;
-}
-#endif
-
-/* check to see if nmbd is running on localhost by looking for a __SAMBA__
- response */
-BOOL nmbd_running(void)
-{
- extern struct in_addr loopback_ip;
- int fd, count, flags;
- struct in_addr *ip_list;
-
- if ((fd = open_socket_in(SOCK_DGRAM, 0, 3,
- interpret_addr("127.0.0.1"), True)) != -1) {
- if ((ip_list = name_query(fd, "__SAMBA__", 0,
- True, True, loopback_ip,
- &count, &flags, NULL)) != NULL) {
- SAFE_FREE(ip_list);
- close(fd);
- return True;
- }
- close (fd);
- }
-
- return False;
-}
-
-
-/* check to see if smbd is running on localhost by trying to open a connection
- then closing it */
-BOOL smbd_running(void)
-{
- static struct cli_state cli;
- extern struct in_addr loopback_ip;
-
- if (!cli_initialise(&cli))
- return False;
-
- if (!cli_connect(&cli, lp_netbios_name(), &loopback_ip)) {
- cli_shutdown(&cli);
- return False;
- }
-
- cli_shutdown(&cli);
- return True;
-}
diff --git a/source4/web/neg_lang.c b/source4/web/neg_lang.c
deleted file mode 100644
index 495596c759..0000000000
--- a/source4/web/neg_lang.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SWAT language handling
-
- 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.
-
- Created by Ryo Kawahara <rkawa@lbe.co.jp>
-*/
-
-#include "includes.h"
-
-/*
- during a file download we first check to see if there is a language
- specific file available. If there is then use that, otherwise
- just open the specified file
-*/
-int web_open(const char *fname, int flags, mode_t mode)
-{
- char *p = NULL;
- char *lang = lang_tdb_current();
- int fd;
- if (lang) {
- asprintf(&p, "lang/%s/%s", lang, fname);
- if (p) {
- fd = sys_open(p, flags, mode);
- free(p);
- if (fd != -1) {
- return fd;
- }
- }
- }
-
- /* fall through to default name */
- return sys_open(fname, flags, mode);
-}
-
-
-struct pri_list {
- float pri;
- char *string;
-};
-
-static int qsort_cmp_list(const void *x, const void *y) {
- struct pri_list *a = (struct pri_list *)x;
- struct pri_list *b = (struct pri_list *)y;
- if (a->pri > b->pri) return -1;
- if (a->pri == b->pri) return 0;
- return 1;
-}
-
-/*
- choose from a list of languages. The list can be comma or space
- separated
- Keep choosing until we get a hit
- Changed to habdle priority -- Simo
-*/
-
-void web_set_lang(const char *lang_string)
-{
- char **lang_list, **count;
- struct pri_list *pl;
- int lang_num, i;
-
- /* build the lang list */
- lang_list = str_list_make(lang_string, ", \t\r\n");
- if (!lang_list) return;
-
- /* sort the list by priority */
- lang_num = 0;
- count = lang_list;
- while (*count && **count) {
- count++;
- lang_num++;
- }
- pl = (struct pri_list *)malloc(sizeof(struct pri_list) * lang_num);
- for (i = 0; i < lang_num; i++) {
- char *pri_code;
- if ((pri_code=strstr(lang_list[i], ";q="))) {
- *pri_code = '\0';
- pri_code += 3;
- sscanf(pri_code, "%f", &(pl[i].pri));
- } else {
- pl[i].pri = 1;
- }
- pl[i].string = strdup(lang_list[i]);
- }
- str_list_free(&lang_list);
-
- qsort(pl, lang_num, sizeof(struct pri_list), QSORT_CAST qsort_cmp_list);
-
- /* it's not an error to not initialise - we just fall back to
- the default */
-
- for (i = 0; i < lang_num; i++) {
- if (lang_tdb_init(pl[i].string)) break;
- }
-
- for (i = 0; i < lang_num; i++) {
- SAFE_FREE(pl[i].string);
- }
- SAFE_FREE(pl);
-
- return;
-}
diff --git a/source4/web/startstop.c b/source4/web/startstop.c
deleted file mode 100644
index 94578dc19e..0000000000
--- a/source4/web/startstop.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- start/stop nmbd and smbd
- Copyright (C) Andrew Tridgell 1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "dynconfig.h"
-
-/** Need to wait for daemons to startup */
-#define SLEEP_TIME 3
-
-/** Startup smbd from web interface. */
-void start_smbd(void)
-{
- pstring binfile;
-
- if (geteuid() != 0) return;
-
- if (fork()) {
- sleep(SLEEP_TIME);
- return;
- }
-
- slprintf(binfile, sizeof(pstring) - 1, "%s/smbd", dyn_SBINDIR);
-
- become_daemon(True);
-
- execl(binfile, binfile, "-D", NULL);
-
- exit(0);
-}
-
-/* startup nmbd */
-void start_nmbd(void)
-{
- pstring binfile;
-
- if (geteuid() != 0) return;
-
- if (fork()) {
- sleep(SLEEP_TIME);
- return;
- }
-
- slprintf(binfile, sizeof(pstring) - 1, "%s/nmbd", dyn_SBINDIR);
-
- become_daemon(True);
-
- execl(binfile, binfile, "-D", NULL);
-
- exit(0);
-}
-
-/** Startup winbindd from web interface. */
-void start_winbindd(void)
-{
- pstring binfile;
-
- if (geteuid() != 0) return;
-
- if (fork()) {
- sleep(SLEEP_TIME);
- return;
- }
-
- slprintf(binfile, sizeof(pstring) - 1, "%s/winbindd", dyn_SBINDIR);
-
- become_daemon(True);
-
- execl(binfile, binfile, NULL);
-
- exit(0);
-}
-
-
-/* stop smbd */
-void stop_smbd(void)
-{
- pid_t pid = pidfile_pid("smbd");
-
- if (geteuid() != 0) return;
-
- if (pid <= 0) return;
-
- kill(pid, SIGTERM);
-}
-
-/* stop nmbd */
-void stop_nmbd(void)
-{
- pid_t pid = pidfile_pid("nmbd");
-
- if (geteuid() != 0) return;
-
- if (pid <= 0) return;
-
- kill(pid, SIGTERM);
-}
-#ifdef WITH_WINBIND
-/* stop winbindd */
-void stop_winbindd(void)
-{
- pid_t pid = pidfile_pid("winbindd");
-
- if (geteuid() != 0) return;
-
- if (pid <= 0) return;
-
- kill(pid, SIGTERM);
-}
-#endif
-/* kill a specified process */
-void kill_pid(pid_t pid)
-{
- if (geteuid() != 0) return;
-
- if (pid <= 0) return;
-
- kill(pid, SIGTERM);
- sleep(SLEEP_TIME);
-}
diff --git a/source4/web/statuspage.c b/source4/web/statuspage.c
deleted file mode 100644
index c83d0af021..0000000000
--- a/source4/web/statuspage.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- web status page
- Copyright (C) Andrew Tridgell 1997-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"
-
-#define PIDMAP struct PidMap
-
-PIDMAP {
- PIDMAP *next, *prev;
- pid_t pid;
- char *machine;
-};
-
-static PIDMAP *pidmap;
-static int PID_or_Machine; /* 0 = show PID, else show Machine name */
-
-static pid_t smbd_pid;
-
-/* from 2nd call on, remove old list */
-static void initPid2Machine (void)
-{
- /* show machine name rather PID on table "Open Files"? */
- if (PID_or_Machine) {
- PIDMAP *p;
-
- for (p = pidmap; p != NULL; ) {
- DLIST_REMOVE(pidmap, p);
- SAFE_FREE(p->machine);
- SAFE_FREE(p);
- }
-
- pidmap = NULL;
- }
-}
-
-/* add new PID <-> Machine name mapping */
-static void addPid2Machine (pid_t pid, char *machine)
-{
- /* show machine name rather PID on table "Open Files"? */
- if (PID_or_Machine) {
- PIDMAP *newmap;
-
- if ((newmap = (PIDMAP *) malloc (sizeof (PIDMAP))) == NULL) {
- /* XXX need error message for this?
- if malloc fails, PID is always shown */
- return;
- }
-
- newmap->pid = pid;
- newmap->machine = strdup (machine);
-
- DLIST_ADD(pidmap, newmap);
- }
-}
-
-/* lookup PID <-> Machine name mapping */
-static char *mapPid2Machine (pid_t pid)
-{
- static char pidbuf [64];
- PIDMAP *map;
-
- /* show machine name rather PID on table "Open Files"? */
- if (PID_or_Machine) {
- for (map = pidmap; map != NULL; map = map->next) {
- if (pid == map->pid) {
- if (map->machine == NULL) /* no machine name */
- break; /* show PID */
-
- return map->machine;
- }
- }
- }
-
- /* PID not in list or machine name NULL? return pid as string */
- snprintf (pidbuf, sizeof (pidbuf) - 1, "%d", pid);
- return pidbuf;
-}
-
-static char *tstring(time_t t)
-{
- static pstring buf;
- pstrcpy(buf, asctime(localtime(&t)));
- all_string_sub(buf," ","&nbsp;",sizeof(buf));
- return buf;
-}
-
-static void print_share_mode(share_mode_entry *e, char *fname)
-{
- d_printf("<tr><td>%s</td>",_(mapPid2Machine(e->pid)));
- d_printf("<td>");
- switch ((e->share_mode>>4)&0xF) {
- case DENY_NONE: d_printf("DENY_NONE"); break;
- case DENY_ALL: d_printf("DENY_ALL "); break;
- case DENY_DOS: d_printf("DENY_DOS "); break;
- case DENY_READ: d_printf("DENY_READ "); break;
- case DENY_WRITE:d_printf("DENY_WRITE "); break;
- }
- d_printf("</td>");
-
- d_printf("<td>");
- switch (e->share_mode&0xF) {
- case 0: d_printf("RDONLY "); break;
- case 1: d_printf("WRONLY "); break;
- case 2: d_printf("RDWR "); break;
- }
- d_printf("</td>");
-
- d_printf("<td>");
- if((e->op_type &
- (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) ==
- (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
- d_printf("EXCLUSIVE+BATCH ");
- else if (e->op_type & EXCLUSIVE_OPLOCK)
- d_printf("EXCLUSIVE ");
- else if (e->op_type & BATCH_OPLOCK)
- d_printf("BATCH ");
- else if (e->op_type & LEVEL_II_OPLOCK)
- d_printf("LEVEL_II ");
- else
- d_printf("NONE ");
- d_printf("</td>");
-
- d_printf("<td>%s</td><td>%s</td></tr>\n",
- fname,tstring(e->time.tv_sec));
-}
-
-
-/* kill off any connections chosen by the user */
-static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state)
-{
- struct connections_data crec;
-
- if (dbuf.dsize != sizeof(crec))
- return 0;
-
- memcpy(&crec, dbuf.dptr, sizeof(crec));
-
- if (crec.cnum == -1 && process_exists(crec.pid)) {
- char buf[30];
- slprintf(buf,sizeof(buf)-1,"kill_%d", (int)crec.pid);
- if (cgi_variable(buf)) {
- kill_pid(crec.pid);
- }
- }
- return 0;
-}
-
-/* traversal fn for showing machine connections */
-static int traverse_fn2(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state)
-{
- struct connections_data crec;
-
- if (dbuf.dsize != sizeof(crec))
- return 0;
-
- memcpy(&crec, dbuf.dptr, sizeof(crec));
-
- if (crec.cnum != -1 || !process_exists(crec.pid) || (crec.pid == smbd_pid))
- return 0;
-
- addPid2Machine (crec.pid, crec.machine);
-
- d_printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td>\n",
- (int)crec.pid,
- crec.machine,crec.addr,
- tstring(crec.start));
- if (geteuid() == 0) {
- d_printf("<td><input type=submit value=\"X\" name=\"kill_%d\"></td>\n",
- (int)crec.pid);
- }
- d_printf("</tr>\n");
-
- return 0;
-}
-
-/* traversal fn for showing share connections */
-static int traverse_fn3(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state)
-{
- struct connections_data crec;
- TALLOC_CTX *mem_ctx;
-
- if (dbuf.dsize != sizeof(crec))
- return 0;
-
- memcpy(&crec, dbuf.dptr, sizeof(crec));
-
- if (crec.cnum == -1 || !process_exists(crec.pid))
- return 0;
-
- mem_ctx = talloc_init("smbgroupedit talloc");
- if (!mem_ctx) return -1;
- d_printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>\n",
- crec.name,uidtoname(crec.uid),
- gidtoname(mem_ctx, crec.gid),(int)crec.pid,
- crec.machine,
- tstring(crec.start));
- talloc_destroy(mem_ctx);
- return 0;
-}
-
-
-/* show the current server status */
-void status_page(void)
-{
- const char *v;
- int autorefresh=0;
- int refresh_interval=30;
- TDB_CONTEXT *tdb;
-
- smbd_pid = pidfile_pid("smbd");
-
- if (cgi_variable("smbd_restart")) {
- stop_smbd();
- start_smbd();
- }
-
- if (cgi_variable("smbd_start")) {
- start_smbd();
- }
-
- if (cgi_variable("smbd_stop")) {
- stop_smbd();
- }
-
- if (cgi_variable("nmbd_restart")) {
- stop_nmbd();
- start_nmbd();
- }
- if (cgi_variable("nmbd_start")) {
- start_nmbd();
- }
-
- if (cgi_variable("nmbd_stop")) {
- stop_nmbd();
- }
-
-#ifdef WITH_WINBIND
- if (cgi_variable("winbindd_restart")) {
- stop_winbindd();
- start_winbindd();
- }
-
- if (cgi_variable("winbindd_start")) {
- start_winbindd();
- }
-
- if (cgi_variable("winbindd_stop")) {
- stop_winbindd();
- }
-#endif
- if (cgi_variable("autorefresh")) {
- autorefresh = 1;
- } else if (cgi_variable("norefresh")) {
- autorefresh = 0;
- } else if (cgi_variable("refresh")) {
- autorefresh = 1;
- }
-
- if ((v=cgi_variable("refresh_interval"))) {
- refresh_interval = atoi(v);
- }
-
- if (cgi_variable("show_client_in_col_1")) {
- PID_or_Machine = 1;
- }
-
- tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
- if (tdb) tdb_traverse(tdb, traverse_fn1, NULL);
-
- initPid2Machine ();
-
- d_printf("<H2>%s</H2>\n", _("Server Status"));
-
- d_printf("<FORM method=post>\n");
-
- if (!autorefresh) {
- d_printf("<input type=submit value=\"%s\" name=autorefresh>\n", _("Auto Refresh"));
- d_printf("<br>%s", _("Refresh Interval: "));
- d_printf("<input type=text size=2 name=\"refresh_interval\" value=%d>\n",
- refresh_interval);
- } else {
- d_printf("<input type=submit value=\"%s\" name=norefresh>\n", _("Stop Refreshing"));
- d_printf("<br>%s%d\n", _("Refresh Interval: "), refresh_interval);
- d_printf("<input type=hidden name=refresh value=1>\n");
- }
-
- d_printf("<p>\n");
-
- if (!tdb) {
- /* open failure either means no connections have been
- made */
- }
-
-
- d_printf("<table>\n");
-
- d_printf("<tr><td>%s</td><td>%s</td></tr>", _("version:"), VERSION);
-
- fflush(stdout);
- d_printf("<tr><td>%s</td><td>%s</td>\n", _("smbd:"), smbd_running()?_("running"):_("not running"));
- if (geteuid() == 0) {
- if (smbd_running()) {
- d_printf("<td><input type=submit name=\"smbd_stop\" value=\"%s\"></td>\n", _("Stop smbd"));
- } else {
- d_printf("<td><input type=submit name=\"smbd_start\" value=\"%s\"></td>\n", _("Start smbd"));
- }
- d_printf("<td><input type=submit name=\"smbd_restart\" value=\"%s\"></td>\n", _("Restart smbd"));
- }
- d_printf("</tr>\n");
-
- fflush(stdout);
- d_printf("<tr><td>%s</td><td>%s</td>\n", _("nmbd:"), nmbd_running()?_("running"):_("not running"));
- if (geteuid() == 0) {
- if (nmbd_running()) {
- d_printf("<td><input type=submit name=\"nmbd_stop\" value=\"%s\"></td>\n", _("Stop nmbd"));
- } else {
- d_printf("<td><input type=submit name=\"nmbd_start\" value=\"%s\"></td>\n", _("Start nmbd"));
- }
- d_printf("<td><input type=submit name=\"nmbd_restart\" value=\"%s\"></td>\n", _("Restart nmbd"));
- }
- d_printf("</tr>\n");
-
-#ifdef WITH_WINBIND
- fflush(stdout);
- d_printf("<tr><td>%s</td><td>%s</td>\n", _("winbindd:"), winbindd_running()?_("running"):_("not running"));
- if (geteuid() == 0) {
- if (winbindd_running()) {
- d_printf("<td><input type=submit name=\"winbindd_stop\" value=\"%s\"></td>\n", _("Stop winbindd"));
- } else {
- d_printf("<td><input type=submit name=\"winbindd_start\" value=\"%s\"></td>\n", _("Start winbindd"));
- }
- d_printf("<td><input type=submit name=\"winbindd_restart\" value=\"%s\"></td>\n", _("Restart winbindd"));
- }
- d_printf("</tr>\n");
-#endif
-
- d_printf("</table>\n");
- fflush(stdout);
-
- d_printf("<p><h3>%s</h3>\n", _("Active Connections"));
- d_printf("<table border=1>\n");
- d_printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th>\n", _("PID"), _("Client"), _("IP address"), _("Date"));
- if (geteuid() == 0) {
- d_printf("<th>%s</th>\n", _("Kill"));
- }
- d_printf("</tr>\n");
-
- if (tdb) tdb_traverse(tdb, traverse_fn2, NULL);
-
- d_printf("</table><p>\n");
-
- d_printf("<p><h3>%s</h3>\n", _("Active Shares"));
- d_printf("<table border=1>\n");
- d_printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n\n",
- _("Share"), _("User"), _("Group"), _("PID"), _("Client"), _("Date"));
-
- if (tdb) tdb_traverse(tdb, traverse_fn3, NULL);
-
- d_printf("</table><p>\n");
-
- d_printf("<h3>%s</h3>\n", _("Open Files"));
- d_printf("<table border=1>\n");
- d_printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n", _("PID"), _("Sharing"), _("R/W"), _("Oplock"), _("File"), _("Date"));
-
- locking_init(1);
- share_mode_forall(print_share_mode);
- locking_end();
- d_printf("</table>\n");
-
- if (tdb) tdb_close(tdb);
-
- d_printf("<br><input type=submit name=\"show_client_in_col_1\" value=\"Show Client in col 1\">\n");
- d_printf("<input type=submit name=\"show_pid_in_col_1\" value=\"Show PID in col 1\">\n");
-
- d_printf("</FORM>\n");
-
- if (autorefresh) {
- /* this little JavaScript allows for automatic refresh
- of the page. There are other methods but this seems
- to be the best alternative */
- d_printf("<script language=\"JavaScript\">\n");
- d_printf("<!--\nsetTimeout('window.location.replace(\"%s/status?refresh_interval=%d&refresh=1\")', %d)\n",
- cgi_baseurl(),
- refresh_interval,
- refresh_interval*1000);
- d_printf("//-->\n</script>\n");
- }
-}
diff --git a/source4/web/swat.c b/source4/web/swat.c
deleted file mode 100644
index ec646f5848..0000000000
--- a/source4/web/swat.c
+++ /dev/null
@@ -1,1343 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba Web Administration Tool
- Version 3.0.0
- Copyright (C) Andrew Tridgell 1997-2002
- Copyright (C) John H Terpstra 2002
-
- 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.
-*/
-
-/**
- * @defgroup swat SWAT - Samba Web Administration Tool
- * @{
- * @file swat.c
- *
- * @brief Samba Web Administration Tool.
- **/
-
-#include "includes.h"
-
-#define GLOBALS_SNUM -1
-
-static BOOL demo_mode = False;
-static BOOL have_write_access = False;
-static BOOL have_read_access = False;
-static int iNumNonAutoPrintServices = 0;
-
-/*
- * Password Management Globals
- */
-#define SWAT_USER "username"
-#define OLD_PSWD "old_passwd"
-#define NEW_PSWD "new_passwd"
-#define NEW2_PSWD "new2_passwd"
-#define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
-#define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
-#define ADD_USER_FLAG "add_user_flag"
-#define DELETE_USER_FLAG "delete_user_flag"
-#define DISABLE_USER_FLAG "disable_user_flag"
-#define ENABLE_USER_FLAG "enable_user_flag"
-#define RHOST "remote_host"
-
-/* we need these because we link to locking*.o */
- void become_root(void) {}
- void unbecome_root(void) {}
-
-/****************************************************************************
-****************************************************************************/
-static int enum_index(int value, const struct enum_list *enumlist)
-{
- int i;
- for (i=0;enumlist[i].name;i++)
- if (value == enumlist[i].value) break;
- return(i);
-}
-
-static char *fix_backslash(const char *str)
-{
- static char newstring[1024];
- char *p = newstring;
-
- while (*str) {
- if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
- else *p++ = *str;
- ++str;
- }
- *p = '\0';
- return newstring;
-}
-
-static char *stripspaceupper(const char *str)
-{
- static char newstring[1024];
- char *p = newstring;
-
- while (*str) {
- if (*str != ' ') *p++ = toupper(*str);
- ++str;
- }
- *p = '\0';
- return newstring;
-}
-
-static char *make_parm_name(const char *label)
-{
- static char parmname[1024];
- char *p = parmname;
-
- while (*label) {
- if (*label == ' ') *p++ = '_';
- else *p++ = *label;
- ++label;
- }
- *p = '\0';
- return parmname;
-}
-
-/****************************************************************************
- include a lump of html in a page
-****************************************************************************/
-static int include_html(const char *fname)
-{
- int fd;
- char buf[1024];
- int ret;
-
- fd = web_open(fname, O_RDONLY, 0);
-
- if (fd == -1) {
- d_printf("ERROR: Can't open %s\n", fname);
- return 0;
- }
-
- while ((ret = read(fd, buf, sizeof(buf))) > 0) {
- write(1, buf, ret);
- }
-
- close(fd);
- return 1;
-}
-
-/****************************************************************************
- start the page with standard stuff
-****************************************************************************/
-static void print_header(void)
-{
- if (!cgi_waspost()) {
- d_printf("Expires: 0\r\n");
- }
- d_printf("Content-type: text/html\r\n\r\n");
-
- if (!include_html("include/header.html")) {
- d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
- d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
- }
-}
-
-/* *******************************************************************
- show parameter label with translated name in the following form
- because showing original and translated label in one line looks
- too long, and showing translated label only is unusable for
- heavy users.
- -------------------------------
- HELP security [combo box][button]
- SECURITY
- -------------------------------
- (capital words are translated by gettext.)
- if no translation is available, then same form as original is
- used.
- "i18n_translated_parm" class is used to change the color of the
- translated parameter with CSS.
- **************************************************************** */
-static const char* get_parm_translated(
- const char* pAnchor, const char* pHelp, const char* pLabel)
-{
- const char* pTranslated = _(pLabel);
- static pstring output;
- if(strcmp(pLabel, pTranslated) != 0)
- {
- snprintf(output, sizeof(output),
- "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
- pAnchor, pHelp, pLabel, pTranslated);
- return output;
- }
- snprintf(output, sizeof(output),
- "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
- pAnchor, pHelp, pLabel);
- return output;
-}
-/****************************************************************************
- finish off the page
-****************************************************************************/
-static void print_footer(void)
-{
- if (!include_html("include/footer.html")) {
- d_printf("\n</BODY>\n</HTML>\n");
- }
-}
-
-/****************************************************************************
- display one editable parameter in a form
-****************************************************************************/
-static void show_parameter(int snum, struct parm_struct *parm)
-{
- int i;
- void *ptr = parm->ptr;
-
- if (parm->class == P_LOCAL && snum >= 0) {
- ptr = lp_local_ptr(snum, ptr);
- }
-
- printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
- switch (parm->type) {
- case P_CHAR:
- d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
- make_parm_name(parm->label), *(char *)ptr);
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
- _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
- break;
-
- case P_LIST:
- d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
- make_parm_name(parm->label));
- if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
- char **list = *(char ***)ptr;
- for (;*list;list++) {
- d_printf("%s%s", *list, ((*(list+1))?" ":""));
- }
- }
- d_printf("\">");
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
- _("Set Default"), make_parm_name(parm->label));
- if (parm->def.lvalue) {
- char **list = (char **)(parm->def.lvalue);
- for (; *list; list++) {
- d_printf("%s%s", *list, ((*(list+1))?" ":""));
- }
- }
- d_printf("\'\">");
- break;
-
- case P_STRING:
- case P_USTRING:
- d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
- make_parm_name(parm->label), *(char **)ptr);
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
- _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
- break;
-
- case P_BOOL:
- d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
- d_printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
- d_printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
- d_printf("</select>");
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
- _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
- break;
-
- case P_BOOLREV:
- d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
- d_printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
- d_printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
- d_printf("</select>");
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
- _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
- break;
-
- case P_INTEGER:
- d_printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm->label), *(int *)ptr);
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
- _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
- break;
-
- case P_OCTAL:
- d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
- _("Set Default"), make_parm_name(parm->label),
- octal_string((int)(parm->def.ivalue)));
- break;
-
- case P_ENUM:
- d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
- for (i=0;parm->enum_list[i].name;i++) {
- if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
- d_printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
- }
- }
- d_printf("</select>");
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
- _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
- break;
- case P_SEP:
- break;
- }
- d_printf("</td></tr>\n");
-}
-
-/****************************************************************************
- display a set of parameters for a service
-****************************************************************************/
-static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
-{
- int i = 0;
- struct parm_struct *parm;
- const char *heading = NULL;
- const char *last_heading = NULL;
-
- while ((parm = lp_next_parameter(snum, &i, allparameters))) {
- if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
- continue;
- if (parm->class == P_SEPARATOR) {
- heading = parm->label;
- continue;
- }
- if (parm->flags & FLAG_HIDE) continue;
- if (snum >= 0) {
- if (printers & !(parm->flags & FLAG_PRINT)) continue;
- if (!printers & !(parm->flags & FLAG_SHARE)) continue;
- }
- if (parm_filter == FLAG_BASIC) {
- if (!(parm->flags & FLAG_BASIC)) {
- void *ptr = parm->ptr;
-
- if (parm->class == P_LOCAL && snum >= 0) {
- ptr = lp_local_ptr(snum, ptr);
- }
-
- switch (parm->type) {
- case P_CHAR:
- if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
- break;
-
- case P_LIST:
- if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
- break;
-
- case P_STRING:
- case P_USTRING:
- if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
- break;
-
- case P_BOOL:
- case P_BOOLREV:
- if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
- break;
-
- case P_INTEGER:
- case P_OCTAL:
- if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
- break;
-
-
- case P_ENUM:
- if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
- break;
- case P_SEP:
- continue;
- }
- }
- if (printers && !(parm->flags & FLAG_PRINT)) continue;
- }
- if (parm_filter == FLAG_WIZARD) {
- if (!((parm->flags & FLAG_WIZARD))) continue;
- }
- if (parm_filter == FLAG_ADVANCED) {
- if (!((parm->flags & FLAG_ADVANCED))) continue;
- }
- if (heading && heading != last_heading) {
- d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
- last_heading = heading;
- }
- show_parameter(snum, parm);
- }
-}
-
-/****************************************************************************
- load the smb.conf file into loadparm.
-****************************************************************************/
-static BOOL load_config(BOOL save_def)
-{
- lp_resetnumservices();
- return lp_load(dyn_CONFIGFILE,False,save_def,False);
-}
-
-/****************************************************************************
- write a config file
-****************************************************************************/
-static void write_config(FILE *f, BOOL show_defaults)
-{
- fprintf(f, "# Samba config file created using SWAT\n");
- fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
- fprintf(f, "# Date: %s\n\n", timestring(time(NULL)));
-
- lp_dump(f, show_defaults, iNumNonAutoPrintServices);
-}
-
-/****************************************************************************
- save and reload the smb.conf config file
-****************************************************************************/
-static int save_reload(int snum)
-{
- FILE *f;
- struct stat st;
-
- f = sys_fopen(dyn_CONFIGFILE,"w");
- if (!f) {
- d_printf("failed to open %s for writing\n", dyn_CONFIGFILE);
- return 0;
- }
-
- /* just in case they have used the buggy xinetd to create the file */
- if (fstat(fileno(f), &st) == 0 &&
- (st.st_mode & S_IWOTH)) {
- fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
- }
-
- write_config(f, False);
- if (snum)
- lp_dump_one(f, False, snum);
- fclose(f);
-
- lp_killunused(NULL);
-
- if (!load_config(False)) {
- d_printf("Can't reload %s\n", dyn_CONFIGFILE);
- return 0;
- }
- iNumNonAutoPrintServices = lp_numservices();
- load_printers();
-
- return 1;
-}
-
-/****************************************************************************
- commit one parameter
-****************************************************************************/
-static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
-{
- int i;
- char *s;
-
- if (snum < 0 && parm->class == P_LOCAL) {
- /* this handles the case where we are changing a local
- variable globally. We need to change the parameter in
- all shares where it is currently set to the default */
- for (i=0;i<lp_numservices();i++) {
- s = lp_servicename(i);
- if (s && (*s) && lp_is_default(i, parm)) {
- lp_do_parameter(i, parm->label, v);
- }
- }
- }
-
- lp_do_parameter(snum, parm->label, v);
-}
-
-/****************************************************************************
- commit a set of parameters for a service
-****************************************************************************/
-static void commit_parameters(int snum)
-{
- int i = 0;
- struct parm_struct *parm;
- pstring label;
- const char *v;
-
- while ((parm = lp_next_parameter(snum, &i, 1))) {
- slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
- if ((v = cgi_variable(label))) {
- if (parm->flags & FLAG_HIDE) continue;
- commit_parameter(snum, parm, v);
- }
- }
-}
-
-/****************************************************************************
- spit out the html for a link with an image
-****************************************************************************/
-static void image_link(const char *name, const char *hlink, const char *src)
-{
- d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
- cgi_baseurl(), hlink, src, name);
-}
-
-/****************************************************************************
- display the main navigation controls at the top of each page along
- with a title
-****************************************************************************/
-static void show_main_buttons(void)
-{
- char *p;
-
- if ((p = cgi_user_name()) && strcmp(p, "root")) {
- d_printf(_("Logged in as <b>%s</b><p>\n"), p);
- }
-
- image_link(_("Home"), "", "images/home.gif");
- if (have_write_access) {
- image_link(_("Globals"), "globals", "images/globals.gif");
- image_link(_("Shares"), "shares", "images/shares.gif");
- image_link(_("Printers"), "printers", "images/printers.gif");
- image_link(_("Wizard"), "wizard", "images/wizard.gif");
- }
- if (have_read_access) {
- image_link(_("Status"), "status", "images/status.gif");
- image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
- }
- image_link(_("Password Management"), "passwd", "images/passwd.gif");
-
- d_printf("<HR>\n");
-}
-
-/****************************************************************************
- * Handle Display/Edit Mode CGI
- ****************************************************************************/
-static void ViewModeBoxes(int mode)
-{
- d_printf("<p>%s\n", _("Configuration View:&nbsp"));
- d_printf("<input type=radio name=\"ViewMode\" value=0 %s>Basic\n", (mode == 0) ? "checked" : "");
- d_printf("<input type=radio name=\"ViewMode\" value=1 %s>Advanced\n", (mode == 1) ? "checked" : "");
- d_printf("<input type=radio name=\"ViewMode\" value=2 %s>Developer\n", (mode == 2) ? "checked" : "");
- d_printf("</p><br>\n");
-}
-
-/****************************************************************************
- display a welcome page
-****************************************************************************/
-static void welcome_page(void)
-{
- include_html("help/welcome.html");
-}
-
-/****************************************************************************
- display the current smb.conf
-****************************************************************************/
-static void viewconfig_page(void)
-{
- int full_view=0;
-
- if (cgi_variable("full_view")) {
- full_view = 1;
- }
-
- d_printf("<H2>%s</H2>\n", _("Current Config"));
- d_printf("<form method=post>\n");
-
- if (full_view) {
- d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
- } else {
- d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
- }
-
- d_printf("<p><pre>");
- write_config(stdout, full_view);
- d_printf("</pre>");
- d_printf("</form>\n");
-}
-
-/****************************************************************************
- second screen of the wizard ... Fetch Configuration Parameters
-****************************************************************************/
-static void wizard_params_page(void)
-{
- unsigned int parm_filter = FLAG_WIZARD;
-
- /* Here we first set and commit all the parameters that were selected
- in the previous screen. */
-
- d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
-
- if (cgi_variable("Commit")) {
- commit_parameters(GLOBALS_SNUM);
- save_reload(0);
- }
-
- d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
-
- if (have_write_access) {
- d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
- }
-
- d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
- d_printf("<p>\n");
-
- d_printf("<table>\n");
- show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
- d_printf("</table>\n");
- d_printf("</form>\n");
-}
-
-/****************************************************************************
- Utility to just rewrite the smb.conf file - effectively just cleans it up
-****************************************************************************/
-static void rewritecfg_file(void)
-{
- commit_parameters(GLOBALS_SNUM);
- save_reload(0);
- d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten"));
-}
-
-/****************************************************************************
- wizard to create/modify the smb.conf file
-****************************************************************************/
-static void wizard_page(void)
-{
- /* Set some variables to collect data from smb.conf */
- int role = 0;
- int winstype = 0;
- int have_home = -1;
- int HomeExpo = 0;
- int SerType = 0;
-
- if (cgi_variable("Rewrite")) {
- (void) rewritecfg_file();
- return;
- }
-
- if (cgi_variable("GetWizardParams")){
- (void) wizard_params_page();
- return;
- }
-
- if (cgi_variable("Commit")){
- SerType = atoi(cgi_variable("ServerType"));
- winstype = atoi(cgi_variable("WINSType"));
- have_home = lp_servicenumber(HOMES_NAME);
- HomeExpo = atoi(cgi_variable("HomeExpo"));
-
- /* Plain text passwords are too badly broken - use encrypted passwords only */
- lp_do_parameter( GLOBALS_SNUM, "encrypt passwords", "Yes");
-
- switch ( SerType ){
- case 0:
- /* Stand-alone Server */
- lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
- lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
- break;
- case 1:
- /* Domain Member */
- lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" );
- lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
- break;
- case 2:
- /* Domain Controller */
- lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
- lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" );
- break;
- }
- switch ( winstype ) {
- case 0:
- lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
- lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
- break;
- case 1:
- lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" );
- lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
- break;
- case 2:
- lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
- lp_do_parameter( GLOBALS_SNUM, "wins server", cgi_variable("WINSAddr"));
- break;
- }
-
- /* Have to create Homes share? */
- if ((HomeExpo == 1) && (have_home == -1)) {
- pstring unix_share;
-
- pstrcpy(unix_share,HOMES_NAME);
- load_config(False);
- lp_copy_service(GLOBALS_SNUM, unix_share);
- iNumNonAutoPrintServices = lp_numservices();
- have_home = lp_servicenumber(HOMES_NAME);
- lp_do_parameter( have_home, "read only", "No");
- lp_do_parameter( have_home, "valid users", "%S");
- lp_do_parameter( have_home, "browseable", "No");
- commit_parameters(have_home);
- }
-
- /* Need to Delete Homes share? */
- if ((HomeExpo == 0) && (have_home != -1)) {
- lp_remove_service(have_home);
- have_home = -1;
- }
-
- commit_parameters(GLOBALS_SNUM);
- save_reload(0);
- }
- else
- {
- /* Now determine smb.conf WINS settings */
- if (lp_wins_support())
- winstype = 1;
- if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
- winstype = 2;
-
-
- /* Do we have a homes share? */
- have_home = lp_servicenumber(HOMES_NAME);
- }
- if ((winstype == 2) && lp_wins_support())
- winstype = 3;
-
- role = lp_server_role();
-
- /* Here we go ... */
- d_printf("<H2>Samba Configuration Wizard</H2>\n");
- d_printf("<form method=post action=wizard>\n");
-
- if (have_write_access) {
- d_printf(_("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n"));
- d_printf(_("The same will happen if you press the commit button."));
- d_printf("<br><br>");
- d_printf("<center>");
- d_printf("<input type=submit name=\"Rewrite\" value=%s> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
- d_printf("<input type=submit name=\"Commit\" value=%s> &nbsp;&nbsp;",_("Commit"));
- d_printf("<input type=submit name=\"GetWizardParams\" value=%s>", _("Edit Parameter Values"));
- d_printf("</center>");
- }
-
- d_printf("<hr>");
- d_printf("<center><table border=0>");
- d_printf("<tr><td><b>%s</b></td>\n", "Server Type:&nbsp;");
- d_printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone&nbsp;</td>", (role == ROLE_STANDALONE) ? "checked" : "");
- d_printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member&nbsp;</td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : "");
- d_printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller&nbsp;</td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
- d_printf("</tr>");
- if (role == ROLE_DOMAIN_BDC) {
- d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
- }
- d_printf("<tr><td><b>%s</b></td>\n", "Configure WINS As:&nbsp;");
- d_printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used&nbsp;</td>", (winstype == 0) ? "checked" : "");
- d_printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use&nbsp;</td>", (winstype == 1) ? "checked" : "");
- d_printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server&nbsp;</td>", (winstype == 2) ? "checked" : "");
- d_printf("<tr><td></td><td></td><td></td><td>Remote WINS Server&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"%s\"></td></tr>",lp_wins_server_list());
- if (winstype == 3) {
- d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Error: WINS Server Mode and WINS Support both set in smb.conf</font></td></tr>");
- d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
- }
- d_printf("</tr>");
- d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories:&nbsp;");
- d_printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
- d_printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
- d_printf("<td></td></tr>");
-
- /* Enable this when we are ready ....
- * d_printf("<tr><td><b>%s</b></td>\n","Is Print Server:&nbsp;");
- * d_printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
- * d_printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
- * d_printf("<td></td></tr>");
- */
-
- d_printf("</table></center>");
- d_printf("<hr>");
-
- d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n"));
- d_printf("</form>\n");
-}
-
-
-/****************************************************************************
- display a globals editing page
-****************************************************************************/
-static void globals_page(void)
-{
- unsigned int parm_filter = FLAG_BASIC;
- int mode = 0;
-
- d_printf("<H2>%s</H2>\n", _("Global Variables"));
-
- if (cgi_variable("Commit")) {
- commit_parameters(GLOBALS_SNUM);
- save_reload(0);
- }
-
- if ( cgi_variable("ViewMode") )
- mode = atoi(cgi_variable("ViewMode"));
-
- d_printf("<form name=\"swatform\" method=post action=globals>\n");
-
- ViewModeBoxes( mode );
- switch ( mode ) {
- case 0:
- parm_filter = FLAG_BASIC;
- break;
- case 1:
- parm_filter = FLAG_ADVANCED;
- break;
- case 2:
- parm_filter = FLAG_DEVELOPER;
- break;
- }
- d_printf("<br>\n");
- if (have_write_access) {
- d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
- _("Commit Changes"));
- }
-
- d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
- _("Reset Values"));
-
- d_printf("<p>\n");
- d_printf("<table>\n");
- show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
- d_printf("</table>\n");
- d_printf("</form>\n");
-}
-
-/****************************************************************************
- display a shares editing page. share is in unix codepage, and must be in
- dos codepage. FIXME !!! JRA.
-****************************************************************************/
-static void shares_page(void)
-{
- const char *share = cgi_variable("share");
- char *s;
- int snum = -1;
- int i;
- int mode = 0;
- unsigned int parm_filter = FLAG_BASIC;
-
- if (share)
- snum = lp_servicenumber(share);
-
- d_printf("<H2>%s</H2>\n", _("Share Parameters"));
-
- if (cgi_variable("Commit") && snum >= 0) {
- commit_parameters(snum);
- save_reload(0);
- }
-
- if (cgi_variable("Delete") && snum >= 0) {
- lp_remove_service(snum);
- save_reload(0);
- share = NULL;
- snum = -1;
- }
-
- if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
- load_config(False);
- lp_copy_service(GLOBALS_SNUM, share);
- iNumNonAutoPrintServices = lp_numservices();
- save_reload(0);
- snum = lp_servicenumber(share);
- }
-
- d_printf("<FORM name=\"swatform\" method=post>\n");
-
- d_printf("<table>\n");
- if ( cgi_variable("ViewMode") )
- mode = atoi(cgi_variable("ViewMode"));
- ViewModeBoxes( mode );
- switch ( mode ) {
- case 0:
- parm_filter = FLAG_BASIC;
- break;
- case 1:
- parm_filter = FLAG_ADVANCED;
- break;
- case 2:
- parm_filter = FLAG_DEVELOPER;
- break;
- }
- d_printf("<br><tr>\n");
- d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
- d_printf("<td><select name=share>\n");
- if (snum < 0)
- d_printf("<option value=\" \"> \n");
- for (i=0;i<lp_numservices();i++) {
- s = lp_servicename(i);
- if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
- d_printf("<option %s value=\"%s\">%s\n",
- (share && strcmp(share,s)==0)?"SELECTED":"",
- s, s);
- }
- }
- d_printf("</select></td>\n");
- if (have_write_access) {
- d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
- }
- d_printf("</tr>\n");
- d_printf("</table>");
- d_printf("<table>");
- if (have_write_access) {
- d_printf("<tr>\n");
- d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
- d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
- }
- d_printf("</table>");
-
-
- if (snum >= 0) {
- if (have_write_access) {
- d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
- }
-
- d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
- d_printf("<p>\n");
- }
-
- if (snum >= 0) {
- d_printf("<table>\n");
- show_parameters(snum, 1, parm_filter, 0);
- d_printf("</table>\n");
- }
-
- d_printf("</FORM>\n");
-}
-
-/*************************************************************
-change a password either locally or remotely
-*************************************************************/
-static BOOL change_password(const char *remote_machine, const char *user_name,
- const char *old_passwd, const char *new_passwd,
- int local_flags)
-{
- BOOL ret = False;
- pstring err_str;
- pstring msg_str;
-
- if (demo_mode) {
- d_printf("%s<p>", _("password change in demo mode rejected\n"));
- return False;
- }
-
- if (remote_machine != NULL) {
- ret = remote_password_change(remote_machine, user_name, old_passwd,
- new_passwd, err_str, sizeof(err_str));
- if(*err_str)
- d_printf("%s\n<p>", err_str);
- return ret;
- }
-
- if(!initialize_password_db(True)) {
- d_printf("Can't setup password database vectors.\n<p>");
- return False;
- }
-
- ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
- msg_str, sizeof(msg_str));
-
- if(*msg_str)
- d_printf("%s\n<p>", msg_str);
- if(*err_str)
- d_printf("%s\n<p>", err_str);
-
- return ret;
-}
-
-/****************************************************************************
- do the stuff required to add or change a password
-****************************************************************************/
-static void chg_passwd(void)
-{
- const char *host;
- BOOL rslt;
- int local_flags = 0;
-
- /* Make sure users name has been specified */
- if (strlen(cgi_variable(SWAT_USER)) == 0) {
- d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
- return;
- }
-
- /*
- * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
- * so if that's what we're doing, skip the rest of the checks
- */
- if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
-
- /*
- * If current user is not root, make sure old password has been specified
- * If REMOTE change, even root must provide old password
- */
- if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
- ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
- d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
- return;
- }
-
- /* If changing a users password on a remote hosts we have to know what host */
- if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
- d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
- return;
- }
-
- /* Make sure new passwords have been specified */
- if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
- (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
- d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
- return;
- }
-
- /* Make sure new passwords was typed correctly twice */
- if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
- d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
- return;
- }
- }
-
- if (cgi_variable(CHG_R_PASSWD_FLAG)) {
- host = cgi_variable(RHOST);
- } else if (am_root()) {
- host = NULL;
- } else {
- host = "127.0.0.1";
- }
-
- /*
- * Set up the local flags.
- */
-
- local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
- local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
- local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
- local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
-
- rslt = change_password(host,
- cgi_variable(SWAT_USER),
- cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
- local_flags);
-
- if(local_flags == 0) {
- d_printf("<p>");
- if (rslt == True) {
- d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
- } else {
- d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
- }
- }
-
- return;
-}
-
-/****************************************************************************
- display a password editing page
-****************************************************************************/
-static void passwd_page(void)
-{
- const char *new_name = cgi_user_name();
-
- /*
- * After the first time through here be nice. If the user
- * changed the User box text to another users name, remember it.
- */
- if (cgi_variable(SWAT_USER)) {
- new_name = cgi_variable(SWAT_USER);
- }
-
- if (!new_name) new_name = "";
-
- d_printf("<H2>%s</H2>\n", _("Server Password Management"));
-
- d_printf("<FORM name=\"swatform\" method=post>\n");
-
- d_printf("<table>\n");
-
- /*
- * Create all the dialog boxes for data collection
- */
- d_printf("<tr><td>%s</td>\n", _(" User Name : "));
- d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
- if (!am_root()) {
- d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
- d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
- }
- d_printf("<tr><td>%s</td>\n", _(" New Password : "));
- d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
- d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
- d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
- d_printf("</table>\n");
-
- /*
- * Create all the control buttons for requesting action
- */
- d_printf("<input type=submit name=%s value=\"%s\">\n",
- CHG_S_PASSWD_FLAG, _("Change Password"));
- if (demo_mode || am_root()) {
- d_printf("<input type=submit name=%s value=\"%s\">\n",
- ADD_USER_FLAG, _("Add New User"));
- d_printf("<input type=submit name=%s value=\"%s\">\n",
- DELETE_USER_FLAG, _("Delete User"));
- d_printf("<input type=submit name=%s value=\"%s\">\n",
- DISABLE_USER_FLAG, _("Disable User"));
- d_printf("<input type=submit name=%s value=\"%s\">\n",
- ENABLE_USER_FLAG, _("Enable User"));
- }
- d_printf("<p></FORM>\n");
-
- /*
- * Do some work if change, add, disable or enable was
- * requested. It could be this is the first time through this
- * code, so there isn't anything to do. */
- if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
- (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
- chg_passwd();
- }
-
- d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
-
- d_printf("<FORM name=\"swatform\" method=post>\n");
-
- d_printf("<table>\n");
-
- /*
- * Create all the dialog boxes for data collection
- */
- d_printf("<tr><td>%s</td>\n", _(" User Name : "));
- d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
- d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
- d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
- d_printf("<tr><td>%s</td>\n", _(" New Password : "));
- d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
- d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
- d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
- d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
- d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
-
- d_printf("</table>");
-
- /*
- * Create all the control buttons for requesting action
- */
- d_printf("<input type=submit name=%s value=\"%s\">",
- CHG_R_PASSWD_FLAG, _("Change Password"));
-
- d_printf("<p></FORM>\n");
-
- /*
- * Do some work if a request has been made to change the
- * password somewhere other than the server. It could be this
- * is the first time through this code, so there isn't
- * anything to do. */
- if (cgi_variable(CHG_R_PASSWD_FLAG)) {
- chg_passwd();
- }
-
-}
-
-/****************************************************************************
- display a printers editing page
-****************************************************************************/
-static void printers_page(void)
-{
- const char *share = cgi_variable("share");
- char *s;
- int snum=-1;
- int i;
- int mode = 0;
- unsigned int parm_filter = FLAG_BASIC;
-
- if (share)
- snum = lp_servicenumber(share);
-
- d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
-
- d_printf("<H3>%s</H3>\n", _("Important Note:"));
- d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
- d_printf(_("are autoloaded printers from "));
- d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
- d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
-
- if (cgi_variable("Commit") && snum >= 0) {
- commit_parameters(snum);
- if (snum >= iNumNonAutoPrintServices)
- save_reload(snum);
- else
- save_reload(0);
- }
-
- if (cgi_variable("Delete") && snum >= 0) {
- lp_remove_service(snum);
- save_reload(0);
- share = NULL;
- snum = -1;
- }
-
- if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
- load_config(False);
- lp_copy_service(GLOBALS_SNUM, share);
- iNumNonAutoPrintServices = lp_numservices();
- snum = lp_servicenumber(share);
- lp_do_parameter(snum, "print ok", "Yes");
- save_reload(0);
- snum = lp_servicenumber(share);
- }
-
- d_printf("<FORM name=\"swatform\" method=post>\n");
-
- if ( cgi_variable("ViewMode") )
- mode = atoi(cgi_variable("ViewMode"));
- ViewModeBoxes( mode );
- switch ( mode ) {
- case 0:
- parm_filter = FLAG_BASIC;
- break;
- case 1:
- parm_filter = FLAG_ADVANCED;
- break;
- case 2:
- parm_filter = FLAG_DEVELOPER;
- break;
- }
- d_printf("<table>\n");
- d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
- d_printf("<td><select name=share>\n");
- if (snum < 0 || !lp_print_ok(snum))
- d_printf("<option value=\" \"> \n");
- for (i=0;i<lp_numservices();i++) {
- s = lp_servicename(i);
- if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
- if (i >= iNumNonAutoPrintServices)
- d_printf("<option %s value=\"%s\">[*]%s\n",
- (share && strcmp(share,s)==0)?"SELECTED":"",
- s, s);
- else
- d_printf("<option %s value=\"%s\">%s\n",
- (share && strcmp(share,s)==0)?"SELECTED":"",
- s, s);
- }
- }
- d_printf("</select></td>");
- if (have_write_access) {
- d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
- }
- d_printf("</tr>");
- d_printf("</table>\n");
-
- if (have_write_access) {
- d_printf("<table>\n");
- d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
- d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
- d_printf("</table>");
- }
-
-
- if (snum >= 0) {
- if (have_write_access) {
- d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
- }
- d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
- d_printf("<p>\n");
- }
-
- if (snum >= 0) {
- d_printf("<table>\n");
- show_parameters(snum, 1, parm_filter, 1);
- d_printf("</table>\n");
- }
- d_printf("</FORM>\n");
-}
-
-
-/**
- * main function for SWAT.
- **/
- int main(int argc, char *argv[])
-{
- extern char *optarg;
- extern int optind;
- int opt;
- char *page;
-
- fault_setup(NULL);
- umask(S_IWGRP | S_IWOTH);
-
-#if defined(HAVE_SET_AUTH_PARAMETERS)
- set_auth_parameters(argc, argv);
-#endif /* HAVE_SET_AUTH_PARAMETERS */
-
- /* just in case it goes wild ... */
- alarm(300);
-
- setlinebuf(stdout);
-
- /* we don't want any SIGPIPE messages */
- BlockSignals(True,SIGPIPE);
-
- dbf = x_fopen("/dev/null", O_WRONLY, 0);
- if (!dbf) dbf = x_stderr;
-
- /* we don't want stderr screwing us up */
- close(2);
- open("/dev/null", O_WRONLY);
-
- while ((opt = getopt(argc, argv,"s:a")) != EOF) {
- switch (opt) {
- case 's':
- pstrcpy(dyn_CONFIGFILE,optarg);
- break;
- case 'a':
- demo_mode = True;
- break;
- }
- }
-
- setup_logging(argv[0],DEBUG_FILE);
- load_config(True);
- iNumNonAutoPrintServices = lp_numservices();
- load_printers();
-
- cgi_setup(dyn_SWATDIR, !demo_mode);
-
- print_header();
-
- cgi_load_variables();
-
- if (!file_exist(dyn_CONFIGFILE, NULL)) {
- have_read_access = True;
- have_write_access = True;
- } else {
- /* check if the authenticated user has write access - if not then
- don't show write options */
- have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
-
- /* if the user doesn't have read access to smb.conf then
- don't let them view it */
- have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
- }
-
- show_main_buttons();
-
- page = cgi_pathinfo();
-
- /* Root gets full functionality */
- if (have_read_access && strcmp(page, "globals")==0) {
- globals_page();
- } else if (have_read_access && strcmp(page,"shares")==0) {
- shares_page();
- } else if (have_read_access && strcmp(page,"printers")==0) {
- printers_page();
- } else if (have_read_access && strcmp(page,"status")==0) {
- status_page();
- } else if (have_read_access && strcmp(page,"viewconfig")==0) {
- viewconfig_page();
- } else if (strcmp(page,"passwd")==0) {
- passwd_page();
- } else if (have_read_access && strcmp(page,"wizard")==0) {
- wizard_page();
- } else if (have_read_access && strcmp(page,"wizard_params")==0) {
- wizard_params_page();
- } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
- rewritecfg_file();
- } else {
- welcome_page();
- }
-
- print_footer();
- return 0;
-}
-
-/** @} **/
diff --git a/source4/wrepld/parser.c b/source4/wrepld/parser.c
deleted file mode 100644
index b619cb0cef..0000000000
--- a/source4/wrepld/parser.c
+++ /dev/null
@@ -1,759 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Jean François Micouleau 1998-2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "wins_repl.h"
-
-extern TALLOC_CTX *mem_ctx;
-
-/****************************************************************************
-grow the send buffer if necessary
-****************************************************************************/
-BOOL grow_buffer(struct BUFFER *buffer, int more)
-{
- char *temp;
-
- DEBUG(10,("grow_buffer: size is: %d offet is:%d growing by %d\n", buffer->length, buffer->offset, more));
-
- /* grow by at least 256 bytes */
- if (more<256)
- more=256;
-
- if (buffer->offset+more >= buffer->length) {
- temp=(char *)talloc_realloc(mem_ctx, buffer->buffer, sizeof(char)* (buffer->length+more) );
- if (temp==NULL) {
- DEBUG(0,("grow_buffer: can't grow buffer\n"));
- return False;
- }
- buffer->length+=more;
- buffer->buffer=temp;
- }
-
- return True;
-}
-
-/****************************************************************************
-check if the buffer has that much data
-****************************************************************************/
-static BOOL check_buffer(struct BUFFER *buffer, int more)
-{
- DEBUG(10,("check_buffer: size is: %d offet is:%d growing by %d\n", buffer->length, buffer->offset, more));
-
- if (buffer->offset+more > buffer->length) {
- DEBUG(10,("check_buffer: buffer smaller than requested, size is: %d needed: %d\n", buffer->length, buffer->offset+more));
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
-decode a WINS_OWNER struct
-****************************************************************************/
-static void decode_wins_owner(struct BUFFER *inbuf, WINS_OWNER *wins_owner)
-{
- if(!check_buffer(inbuf, 24))
- return;
-
- wins_owner->address.s_addr=IVAL(inbuf->buffer, inbuf->offset);
- wins_owner->max_version=((SMB_BIG_UINT)RIVAL(inbuf->buffer, inbuf->offset+4))<<32;
- wins_owner->max_version|=RIVAL(inbuf->buffer, inbuf->offset+8);
- wins_owner->min_version=((SMB_BIG_UINT)RIVAL(inbuf->buffer, inbuf->offset+12))<<32;
- wins_owner->min_version|=RIVAL(inbuf->buffer, inbuf->offset+16);
- wins_owner->type=RIVAL(inbuf->buffer, inbuf->offset+20);
- inbuf->offset+=24;
-
-}
-
-/****************************************************************************
-decode a WINS_NAME struct
-****************************************************************************/
-static void decode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name)
-{
- char *p;
- int i;
-
- if(!check_buffer(outbuf, 40))
- return;
-
- wins_name->name_len=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
- memcpy(wins_name->name,outbuf->buffer+outbuf->offset, 15);
- wins_name->name[15]='\0';
- if((p = strchr(wins_name->name,' ')) != NULL)
- *p = 0;
-
- outbuf->offset+=15;
-
- wins_name->type=(int)outbuf->buffer[outbuf->offset++];
-
- /*
- * fix to bug in WINS replication,
- * present in all versions including W2K SP2 !
- */
- if (wins_name->name[0]==0x1B) {
- wins_name->name[0]=(char)wins_name->type;
- wins_name->type=0x1B;
- }
-
- wins_name->empty=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
-
- wins_name->name_flag=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
- wins_name->group_flag=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
- wins_name->id=((SMB_BIG_UINT)RIVAL(outbuf->buffer, outbuf->offset))<<32;
- outbuf->offset+=4;
- wins_name->id|=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
-
- /* special groups have multiple address */
- if (wins_name->name_flag & 2) {
- if(!check_buffer(outbuf, 4))
- return;
- wins_name->num_ip=IVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
- }
- else
- wins_name->num_ip=1;
-
- if(!check_buffer(outbuf, 4))
- return;
- wins_name->owner.s_addr=IVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
-
- if (wins_name->name_flag & 2) {
- wins_name->others=(struct in_addr *)talloc(mem_ctx, sizeof(struct in_addr)*wins_name->num_ip);
- if (wins_name->others==NULL)
- return;
-
- if(!check_buffer(outbuf, 4*wins_name->num_ip))
- return;
- for (i=0; i<wins_name->num_ip; i++) {
- wins_name->others[i].s_addr=IVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
- }
- }
-
- if(!check_buffer(outbuf, 4))
- return;
- wins_name->foo=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
-
-}
-
-/****************************************************************************
-decode a update notification request
-****************************************************************************/
-static void decode_update_notify_request(struct BUFFER *inbuf, UPDATE_NOTIFY_REQUEST *un_rq)
-{
- int i;
-
- if(!check_buffer(inbuf, 4))
- return;
- un_rq->partner_count=RIVAL(inbuf->buffer, inbuf->offset);
- inbuf->offset+=4;
-
- un_rq->wins_owner=(WINS_OWNER *)talloc(mem_ctx, un_rq->partner_count*sizeof(WINS_OWNER));
- if (un_rq->wins_owner==NULL)
- return;
-
- for (i=0; i<un_rq->partner_count; i++)
- decode_wins_owner(inbuf, &un_rq->wins_owner[i]);
-
- if(!check_buffer(inbuf, 4))
- return;
- un_rq->initiating_wins_server.s_addr=IVAL(inbuf->buffer, inbuf->offset);
- inbuf->offset+=4;
-}
-
-/****************************************************************************
-decode a send entries request
-****************************************************************************/
-static void decode_send_entries_request(struct BUFFER *inbuf, SEND_ENTRIES_REQUEST *se_rq)
-{
- decode_wins_owner(inbuf, &se_rq->wins_owner);
-}
-
-/****************************************************************************
-decode a send entries reply
-****************************************************************************/
-static void decode_send_entries_reply(struct BUFFER *inbuf, SEND_ENTRIES_REPLY *se_rp)
-{
- int i;
-
- if(!check_buffer(inbuf, 4))
- return;
- se_rp->max_names = RIVAL(inbuf->buffer, inbuf->offset);
- inbuf->offset+=4;
-
- se_rp->wins_name=(WINS_NAME *)talloc(mem_ctx, se_rp->max_names*sizeof(WINS_NAME));
- if (se_rp->wins_name==NULL)
- return;
-
- for (i=0; i<se_rp->max_names; i++)
- decode_wins_name(inbuf, &se_rp->wins_name[i]);
-}
-
-/****************************************************************************
-decode a add version number map table reply
-****************************************************************************/
-static void decode_add_version_number_map_table_reply(struct BUFFER *inbuf, AVMT_REP *avmt_rep)
-{
- int i;
-
- if(!check_buffer(inbuf, 4))
- return;
-
- avmt_rep->partner_count=RIVAL(inbuf->buffer, inbuf->offset);
- inbuf->offset+=4;
-
- avmt_rep->wins_owner=(WINS_OWNER *)talloc(mem_ctx, avmt_rep->partner_count*sizeof(WINS_OWNER));
- if (avmt_rep->wins_owner==NULL)
- return;
-
- for (i=0; i<avmt_rep->partner_count; i++)
- decode_wins_owner(inbuf, &avmt_rep->wins_owner[i]);
-
- if(!check_buffer(inbuf, 4))
- return;
- avmt_rep->initiating_wins_server.s_addr=IVAL(inbuf->buffer, inbuf->offset);
- inbuf->offset+=4;
-}
-
-/****************************************************************************
-decode a replicate packet and fill a structure
-****************************************************************************/
-static void decode_replicate(struct BUFFER *inbuf, REPLICATE *rep)
-{
- if(!check_buffer(inbuf, 4))
- return;
-
- rep->msg_type = RIVAL(inbuf->buffer, inbuf->offset);
-
- inbuf->offset+=4;
-
- switch (rep->msg_type) {
- case 0:
- break;
- case 1:
- /* add version number map table reply */
- decode_add_version_number_map_table_reply(inbuf, &rep->avmt_rep);
- break;
- case 2:
- /* send entry request */
- decode_send_entries_request(inbuf, &rep->se_rq);
- break;
- case 3:
- /* send entry request */
- decode_send_entries_reply(inbuf, &rep->se_rp);
- break;
- case 4:
- /* update notification request */
- decode_update_notify_request(inbuf, &rep->un_rq);
- break;
- default:
- DEBUG(0,("decode_replicate: unknown message type:%d\n", rep->msg_type));
- break;
- }
-}
-
-/****************************************************************************
-read the generic header and fill the struct.
-****************************************************************************/
-static void read_generic_header(struct BUFFER *inbuf, generic_header *q)
-{
- if(!check_buffer(inbuf, 16))
- return;
-
- q->data_size = RIVAL(inbuf->buffer, inbuf->offset+0);
- q->opcode = RIVAL(inbuf->buffer, inbuf->offset+4);
- q->assoc_ctx = RIVAL(inbuf->buffer, inbuf->offset+8);
- q->mess_type = RIVAL(inbuf->buffer, inbuf->offset+12);
-}
-
-/*******************************************************************
-decode a start association request
-********************************************************************/
-static void decode_start_assoc_request(struct BUFFER *inbuf, START_ASSOC_REQUEST *q)
-{
- if(!check_buffer(inbuf, 8))
- return;
-
- q->assoc_ctx = RIVAL(inbuf->buffer, inbuf->offset+0);
- q->min_ver = RSVAL(inbuf->buffer, inbuf->offset+4);
- q->maj_ver = RSVAL(inbuf->buffer, inbuf->offset+6);
-}
-
-/*******************************************************************
-decode a start association reply
-********************************************************************/
-static void decode_start_assoc_reply(struct BUFFER *inbuf, START_ASSOC_REPLY *r)
-{
- if(!check_buffer(inbuf, 8))
- return;
-
- r->assoc_ctx=RIVAL(inbuf->buffer, inbuf->offset+0);
- r->min_ver = RSVAL(inbuf->buffer, inbuf->offset+4);
- r->maj_ver = RSVAL(inbuf->buffer, inbuf->offset+6);
-}
-
-/*******************************************************************
-decode a start association reply
-********************************************************************/
-static void decode_stop_assoc(struct BUFFER *inbuf, STOP_ASSOC *r)
-{
- if(!check_buffer(inbuf, 4))
- return;
-
- r->reason=RIVAL(inbuf->buffer, inbuf->offset);
-}
-
-/****************************************************************************
-decode a packet and fill a generic structure
-****************************************************************************/
-void decode_generic_packet(struct BUFFER *inbuf, GENERIC_PACKET *q)
-{
- read_generic_header(inbuf, &q->header);
-
- inbuf->offset+=16;
-
- switch (q->header.mess_type) {
- case 0:
- decode_start_assoc_request(inbuf, &q->sa_rq);
- break;
- case 1:
- decode_start_assoc_reply(inbuf, &q->sa_rp);
- break;
- case 2:
- decode_stop_assoc(inbuf, &q->so);
- break;
- case 3:
- decode_replicate(inbuf, &q->rep);
- break;
- default:
- DEBUG(0,("decode_generic_packet: unknown message type:%d\n", q->header.mess_type));
- break;
- }
-}
-
-/****************************************************************************
-encode a WINS_OWNER struct
-****************************************************************************/
-static void encode_wins_owner(struct BUFFER *outbuf, WINS_OWNER *wins_owner)
-{
- if (!grow_buffer(outbuf, 24))
- return;
-
- SIVAL(outbuf->buffer, outbuf->offset, wins_owner->address.s_addr);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, (int)(wins_owner->max_version>>32));
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, (int)(wins_owner->max_version&0xffffffff));
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->min_version>>32);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->min_version&0xffffffff);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->type);
- outbuf->offset+=4;
-
-}
-
-/****************************************************************************
-encode a WINS_NAME struct
-****************************************************************************/
-static void encode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name)
-{
- int i;
-
- if (!grow_buffer(outbuf, 48+(4*wins_name->num_ip)))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->name_len);
- outbuf->offset+=4;
-
- memset(outbuf->buffer+outbuf->offset, ' ', 15);
-
- /* to prevent copying the leading \0 */
- memcpy(outbuf->buffer+outbuf->offset, wins_name->name, strlen(wins_name->name));
- outbuf->offset+=15;
-
- outbuf->buffer[outbuf->offset++]=(char)wins_name->type;
-
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->empty);
- outbuf->offset+=4;
-
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->name_flag);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->group_flag);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->id>>32);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->id);
- outbuf->offset+=4;
-
- if (wins_name->name_flag & 2) {
- SIVAL(outbuf->buffer, outbuf->offset, wins_name->num_ip);
- outbuf->offset+=4;
- }
-
- SIVAL(outbuf->buffer, outbuf->offset, wins_name->owner.s_addr);
- outbuf->offset+=4;
-
- if (wins_name->name_flag & 2) {
- for (i=0;i<wins_name->num_ip;i++) {
- SIVAL(outbuf->buffer, outbuf->offset, wins_name->others[i].s_addr);
- outbuf->offset+=4;
- }
- }
-
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->foo);
- outbuf->offset+=4;
-}
-
-/****************************************************************************
-encode a update notification request
-****************************************************************************/
-static void encode_update_notify_request(struct BUFFER *outbuf, UPDATE_NOTIFY_REQUEST *un_rq)
-{
- int i;
-
- if (!grow_buffer(outbuf, 8))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, un_rq->partner_count);
- outbuf->offset+=4;
-
- for (i=0; i<un_rq->partner_count; i++)
- encode_wins_owner(outbuf, &un_rq->wins_owner[i]);
-
- SIVAL(outbuf->buffer, outbuf->offset, un_rq->initiating_wins_server.s_addr);
- outbuf->offset+=4;
-
-}
-
-/****************************************************************************
-decode a send entries request
-****************************************************************************/
-static void encode_send_entries_request(struct BUFFER *outbuf, SEND_ENTRIES_REQUEST *se_rq)
-{
- encode_wins_owner(outbuf, &se_rq->wins_owner);
-}
-
-/****************************************************************************
-decode a send entries reply
-****************************************************************************/
-static void encode_send_entries_reply(struct BUFFER *outbuf, SEND_ENTRIES_REPLY *se_rp)
-{
- int i;
-
- if (!grow_buffer(outbuf, 4))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, se_rp->max_names);
- outbuf->offset+=4;
-
- for (i=0; i<se_rp->max_names; i++)
- encode_wins_name(outbuf, &se_rp->wins_name[i]);
-
-}
-
-/****************************************************************************
-encode a add version number map table reply
-****************************************************************************/
-static void encode_add_version_number_map_table_reply(struct BUFFER *outbuf, AVMT_REP *avmt_rep)
-{
- int i;
-
- if (!grow_buffer(outbuf, 8))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, avmt_rep->partner_count);
- outbuf->offset+=4;
-
- for (i=0; i<avmt_rep->partner_count; i++)
- encode_wins_owner(outbuf, &avmt_rep->wins_owner[i]);
-
- SIVAL(outbuf->buffer, outbuf->offset, avmt_rep->initiating_wins_server.s_addr);
- outbuf->offset+=4;
-
-}
-
-/****************************************************************************
-decode a replicate packet and fill a structure
-****************************************************************************/
-static void encode_replicate(struct BUFFER *outbuf, REPLICATE *rep)
-{
- if (!grow_buffer(outbuf, 4))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, rep->msg_type);
- outbuf->offset+=4;
-
- switch (rep->msg_type) {
- case 0:
- break;
- case 1:
- /* add version number map table reply */
- encode_add_version_number_map_table_reply(outbuf, &rep->avmt_rep);
- break;
- case 2:
- /* send entry request */
- encode_send_entries_request(outbuf, &rep->se_rq);
- break;
- case 3:
- /* send entry request */
- encode_send_entries_reply(outbuf, &rep->se_rp);
- break;
- case 4:
- /* update notification request */
- encode_update_notify_request(outbuf, &rep->un_rq);
- break;
- default:
- DEBUG(0,("encode_replicate: unknown message type:%d\n", rep->msg_type));
- break;
- }
-}
-
-/****************************************************************************
-write the generic header.
-****************************************************************************/
-static void write_generic_header(struct BUFFER *outbuf, generic_header *r)
-{
- RSIVAL(outbuf->buffer, 0, r->data_size);
- RSIVAL(outbuf->buffer, 4, r->opcode);
- RSIVAL(outbuf->buffer, 8, r->assoc_ctx);
- RSIVAL(outbuf->buffer,12, r->mess_type);
-}
-
-/*******************************************************************
-decode a start association request
-********************************************************************/
-static void encode_start_assoc_request(struct BUFFER *outbuf, START_ASSOC_REQUEST *q)
-{
- if (!grow_buffer(outbuf, 45))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, q->assoc_ctx);
- RSSVAL(outbuf->buffer, outbuf->offset+4, q->min_ver);
- RSSVAL(outbuf->buffer, outbuf->offset+6, q->maj_ver);
-
- outbuf->offset=45;
-}
-
-/*******************************************************************
-decode a start association reply
-********************************************************************/
-static void encode_start_assoc_reply(struct BUFFER *outbuf, START_ASSOC_REPLY *r)
-{
- if (!grow_buffer(outbuf, 45))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, r->assoc_ctx);
- RSSVAL(outbuf->buffer, outbuf->offset+4, r->min_ver);
- RSSVAL(outbuf->buffer, outbuf->offset+6, r->maj_ver);
-
- outbuf->offset=45;
-}
-
-/*******************************************************************
-decode a start association reply
-********************************************************************/
-static void encode_stop_assoc(struct BUFFER *outbuf, STOP_ASSOC *r)
-{
- if (!grow_buffer(outbuf, 44))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, r->reason);
-
- outbuf->offset=44;
-}
-
-/****************************************************************************
-write the generic header size.
-****************************************************************************/
-static void write_generic_header_size(generic_header *r, int size)
-{
- /* the buffer size is the total size minus the size field */
- r->data_size=size-4;
-}
-
-/****************************************************************************
-encode a packet and read a generic structure
-****************************************************************************/
-void encode_generic_packet(struct BUFFER *outbuf, GENERIC_PACKET *q)
-{
- if (!grow_buffer(outbuf, 16))
- return;
-
- outbuf->offset=16;
-
- switch (q->header.mess_type) {
- case 0:
- encode_start_assoc_request(outbuf, &q->sa_rq);
- break;
- case 1:
- encode_start_assoc_reply(outbuf, &q->sa_rp);
- break;
- case 2:
- encode_stop_assoc(outbuf, &q->so);
- break;
- case 3:
- encode_replicate(outbuf, &q->rep);
- break;
- default:
- DEBUG(0,("encode_generic_packet: unknown message type:%d\n", q->header.mess_type));
- break;
- }
-
- write_generic_header_size(&q->header, outbuf->offset);
- write_generic_header(outbuf, &q->header);
-}
-
-
-/****************************************************************************
-dump a WINS_OWNER structure
-****************************************************************************/
-static void dump_wins_owner(WINS_OWNER *wins_owner)
-{
- DEBUGADD(10,("\t\t\t\taddress : %s\n", inet_ntoa(wins_owner->address)));
- DEBUGADD(10,("\t\t\t\tmax version: %d\n", (int)wins_owner->max_version));
- DEBUGADD(10,("\t\t\t\tmin version: %d\n", (int)wins_owner->min_version));
- DEBUGADD(10,("\t\t\t\ttype : %d\n", wins_owner->type));
-}
-
-/****************************************************************************
-dump a WINS_NAME structure
-****************************************************************************/
-static void dump_wins_name(WINS_NAME *wins_name)
-{
- fstring name;
- int i;
-
- strncpy(name, wins_name->name, 15);
-
- DEBUGADD(10,("name: %d, %s<%02x> %x,%x, %d %s %d ", wins_name->name_len, name, wins_name->type,
- wins_name->name_flag, wins_name->group_flag, (int)wins_name->id,
- inet_ntoa(wins_name->owner), wins_name->num_ip));
-
- if (wins_name->num_ip!=1)
- for (i=0; i<wins_name->num_ip; i++)
- DEBUGADD(10,("%s ", inet_ntoa(wins_name->others[i])));
-
- DEBUGADD(10,("\n"));
-}
-
-/****************************************************************************
-dump a replicate structure
-****************************************************************************/
-static void dump_replicate(REPLICATE *rep)
-{
- int i;
-
- DEBUGADD(5,("\t\tmsg_type: %d ", rep->msg_type));
-
- switch (rep->msg_type) {
- case 0:
- DEBUGADD(5,("(Add Version Map Table Request)\n"));
- break;
- case 1:
- DEBUGADD(5,("(Add Version Map Table Reply)\n"));
- DEBUGADD(5,("\t\t\tpartner_count : %d\n", rep->avmt_rep.partner_count));
- for (i=0; i<rep->avmt_rep.partner_count; i++)
- dump_wins_owner(&rep->avmt_rep.wins_owner[i]);
- DEBUGADD(5,("\t\t\tinitiating_wins_server: %s\n", inet_ntoa(rep->avmt_rep.initiating_wins_server)));
- break;
- case 2:
- DEBUGADD(5,("(Send Entries Request)\n"));
- dump_wins_owner(&rep->se_rq.wins_owner);
- break;
- case 3:
- DEBUGADD(5,("(Send Entries Reply)\n"));
- DEBUGADD(5,("\t\t\tmax_names : %d\n", rep->se_rp.max_names));
- for (i=0; i<rep->se_rp.max_names; i++)
- dump_wins_name(&rep->se_rp.wins_name[i]);
- break;
- case 4:
- DEBUGADD(5,("(Update Notify Request)\n"));
- DEBUGADD(5,("\t\t\tpartner_count : %d\n", rep->un_rq.partner_count));
- for (i=0; i<rep->un_rq.partner_count; i++)
- dump_wins_owner(&rep->un_rq.wins_owner[i]);
- DEBUGADD(5,("\t\t\tinitiating_wins_server: %s\n", inet_ntoa(rep->un_rq.initiating_wins_server)));
- break;
- default:
- DEBUG(5,("\n"));
- break;
- }
-}
-
-/****************************************************************************
-dump a generic structure
-****************************************************************************/
-void dump_generic_packet(GENERIC_PACKET *q)
-{
- DEBUG(5,("dump_generic_packet:\n"));
- DEBUGADD(5,("\tdata_size: %08x\n", q->header.data_size));
- DEBUGADD(5,("\topcode : %08x\n", q->header.opcode));
- DEBUGADD(5,("\tassoc_ctx: %08x\n", q->header.assoc_ctx));
- DEBUGADD(5,("\tmess_type: %08x ", q->header.mess_type));
-
- switch (q->header.mess_type) {
- case 0:
- DEBUGADD(5,("(Start Association Request)\n"));
- DEBUGADD(5,("\t\tassoc_ctx: %08x\n", q->sa_rq.assoc_ctx));
- DEBUGADD(5,("\t\tmin_ver : %04x\n", q->sa_rq.min_ver));
- DEBUGADD(5,("\t\tmaj_ver : %04x\n", q->sa_rq.maj_ver));
- break;
- case 1:
- DEBUGADD(5,("(Start Association Reply)\n"));
- DEBUGADD(5,("\t\tassoc_ctx: %08x\n", q->sa_rp.assoc_ctx));
- DEBUGADD(5,("\t\tmin_ver : %04x\n", q->sa_rp.min_ver));
- DEBUGADD(5,("\t\tmaj_ver : %04x\n", q->sa_rp.maj_ver));
- break;
- case 2:
- DEBUGADD(5,("(Stop Association)\n"));
- DEBUGADD(5,("\t\treason: %08x\n", q->so.reason));
- break;
- case 3:
- DEBUGADD(5,("(Replication Message)\n"));
- dump_replicate(&q->rep);
- break;
- default:
- DEBUG(5,("\n"));
- break;
- }
-
-}
-
-/****************************************************************************
-generate a stop packet
-****************************************************************************/
-void stop_packet(GENERIC_PACKET *q, GENERIC_PACKET *r, int reason)
-{
- r->header.opcode=OPCODE_NON_NBT;
- r->header.assoc_ctx=get_server_assoc(q->header.assoc_ctx);
- r->header.mess_type=MESSAGE_TYPE_STOP_ASSOC;
- r->so.reason=reason;
-
-}
-
-
diff --git a/source4/wrepld/partners.c b/source4/wrepld/partners.c
deleted file mode 100644
index 2387f5b45f..0000000000
--- a/source4/wrepld/partners.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- process incoming packets - main loop
- Copyright (C) Jean François Micouleau 1998-2002.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "wins_repl.h"
-
-/* we can exchange info with 64 partners at any given time */
-WINS_PARTNER current_partners[64];
-int total_current_partners;
-
-/*******************************************************************
-verify if we know this partner
-********************************************************************/
-BOOL check_partner(int assoc)
-{
- int i;
-
- DEBUG(5,("check_partner: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==assoc)
- return True;
-
- return False;
-}
-
-/*******************************************************************
-add a new entry to the list
-********************************************************************/
-BOOL add_partner(int client_assoc, int server_assoc, BOOL pull, BOOL push)
-{
- DEBUG(5,("add_partner: total_current_partners: %d\n", total_current_partners));
-
- if (total_current_partners==64)
- return False;
-
- current_partners[total_current_partners].client_assoc=client_assoc;
- current_partners[total_current_partners].server_assoc=server_assoc;
- current_partners[total_current_partners].pull_partner=pull;
- current_partners[total_current_partners].push_partner=push;
-
- total_current_partners++;
-
- return True;
-}
-
-/*******************************************************************
-remove an entry to the list
-********************************************************************/
-BOOL remove_partner(int client_assoc)
-{
- int i,j;
-
- DEBUG(5,("remove_partner: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; current_partners[i].client_assoc!=client_assoc && i<total_current_partners; i++)
- ;
-
- if (i==total_current_partners)
- return False;
-
- for (j=i+1; j<total_current_partners; j++) {
- current_partners[j-1].client_assoc=current_partners[j].client_assoc;
- current_partners[j-1].server_assoc=current_partners[j].server_assoc;
- current_partners[j-1].pull_partner=current_partners[j].pull_partner;
- current_partners[j-1].push_partner=current_partners[j].push_partner;
- current_partners[j-1].partner_server.s_addr=current_partners[j].partner_server.s_addr;
- current_partners[j-1].other_server.s_addr=current_partners[j].other_server.s_addr;
- }
-
- total_current_partners--;
-
- return True;
-}
-
-/*******************************************************************
-link the client and server context
-********************************************************************/
-BOOL update_server_partner(int client_assoc, int server_assoc)
-{
- int i;
-
- DEBUG(5,("update_server_partner: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==client_assoc) {
- current_partners[i].server_assoc=server_assoc;
- return True;
- }
-
- return False;
-}
-
-/*******************************************************************
-verify if it's a pull partner
-********************************************************************/
-BOOL check_pull_partner(int assoc)
-{
- int i;
-
- DEBUG(5,("check_pull_partner: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==assoc &&
- current_partners[i].pull_partner==True)
- return True;
-
- return False;
-}
-
-/*******************************************************************
-verify if it's a push partner
-********************************************************************/
-BOOL check_push_partner(int assoc)
-{
- int i;
-
- DEBUG(5,("check_push_partner: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==assoc &&
- current_partners[i].push_partner==True)
- return True;
-
- return False;
-}
-
-/*******************************************************************
-return the server ctx linked to the client ctx
-********************************************************************/
-int get_server_assoc(int assoc)
-{
- int i;
-
- DEBUG(5,("get_server_assoc: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==assoc)
- return current_partners[i].server_assoc;
-
- return 0;
-}
-
-
-/*******************************************************************
-link the client and server context
-********************************************************************/
-BOOL write_server_assoc_table(int client_assoc, struct in_addr partner, struct in_addr server)
-{
- int i;
-
- DEBUG(5,("write_server_assoc_table: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==client_assoc) {
- current_partners[i].partner_server=partner;
- current_partners[i].other_server=server;
- return True;
- }
-
- return False;
-}
-
-/*******************************************************************
-link the client and server context
-********************************************************************/
-BOOL get_server_assoc_table(int client_assoc, struct in_addr *partner, struct in_addr *server)
-{
- int i;
-
- DEBUG(5,("get_server_assoc_table: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==client_assoc) {
- partner->s_addr=current_partners[i].partner_server.s_addr;
- server->s_addr=current_partners[i].other_server.s_addr;
- return True;
- }
-
- return False;
-}
-
-
diff --git a/source4/wrepld/process.c b/source4/wrepld/process.c
deleted file mode 100644
index 1f96dc996c..0000000000
--- a/source4/wrepld/process.c
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- process incoming packets - main loop
- Copyright (C) Jean François Micouleau 1998-2002.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "wins_repl.h"
-
-extern fd_set *listen_set;
-extern int listen_number;
-extern int *sock_array;
-
-WINS_OWNER global_wins_table[64][64];
-int partner_count;
-
-TALLOC_CTX *mem_ctx;
-
-#define WINS_LIST "wins.tdb"
-#define INFO_VERSION "INFO/version"
-#define INFO_COUNT "INFO/num_entries"
-#define INFO_ID_HIGH "INFO/id_high"
-#define INFO_ID_LOW "INFO/id_low"
-#define ENTRY_PREFIX "ENTRY/"
-
-
-/*******************************************************************
-fill the header of a reply.
-********************************************************************/
-static void fill_header(GENERIC_PACKET *g, int opcode, int ctx, int mess)
-{
- if (g==NULL)
- return;
-
- g->header.opcode=opcode;
- g->header.assoc_ctx=ctx;
- g->header.mess_type=mess;
-}
-
-/*******************************************************************
-dump the global table, that's a debug code.
-********************************************************************/
-static void dump_global_table(void)
-{
- int i,j;
-
- for (i=0;i<partner_count;i++) {
- DEBUG(10,("\n%d ", i));
- for (j=0; global_wins_table[i][j].address.s_addr!=0; j++)
- DEBUG(10,("%s:%d \t", inet_ntoa(global_wins_table[i][j].address),
- (int)global_wins_table[i][j].max_version));
- }
- DEBUG(10,("\n"));
-}
-
-/*******************************************************************
-start association
-********************************************************************/
-static void start_assoc_process(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- /*
- * add this request to our current wins partners list
- * this list is used to know with who we are in contact
- *
- */
- r->sa_rp.assoc_ctx=time(NULL);
- fill_header(r, OPCODE_NON_NBT, q->sa_rq.assoc_ctx, MESSAGE_TYPE_START_ASSOC_REPLY);
-
- /* reply we are a NT4 server */
-
- /* w2K is min=2, maj=5 */
-
- r->sa_rp.min_ver=1;
- r->sa_rp.maj_ver=1;
-
- add_partner(r->sa_rp.assoc_ctx, q->sa_rq.assoc_ctx, False, False);
-}
-
-/*******************************************************************
-start association reply
-********************************************************************/
-static void start_assoc_reply(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- int i;
-
- /* check if we have already registered this client */
- if (!check_partner(q->header.assoc_ctx)) {
- DEBUG(0,("start_assoc_reply: unknown client\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- if (!update_server_partner(q->header.assoc_ctx, q->sa_rp.assoc_ctx)) {
- DEBUG(0,("start_assoc_reply: can't update server ctx\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- /* if pull, request map table */
- if (check_pull_partner(q->header.assoc_ctx)) {
- fill_header(r, OPCODE_NON_NBT, get_server_assoc(q->header.assoc_ctx), MESSAGE_TYPE_REPLICATE);
-
- r->rep.msg_type=MESSAGE_REP_ADD_VERSION_REQUEST;
- DEBUG(5,("start_assoc_reply: requesting map table\n"));
-
- return;
- }
-
- /* if push, send our table */
- if (check_push_partner(q->header.assoc_ctx)) {
- fill_header(r, OPCODE_NON_NBT, get_server_assoc(q->header.assoc_ctx), MESSAGE_TYPE_REPLICATE);
- r->rep.msg_type=MESSAGE_REP_UPDATE_NOTIFY_REQUEST;
- r->rep.un_rq.partner_count=partner_count;
-
- r->rep.un_rq.wins_owner=(WINS_OWNER *)talloc(mem_ctx, partner_count*sizeof(WINS_OWNER));
- if (r->rep.un_rq.wins_owner==NULL) {
- DEBUG(0,("start_assoc_reply: can't alloc memory\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- for (i=0; i<partner_count; i++)
- r->rep.un_rq.wins_owner[i]=global_wins_table[0][i];
-
- DEBUG(5,("start_assoc_reply: sending update table\n"));
- return;
- }
-
- /* neither push/pull, stop */
- /* we should not come here */
- DEBUG(0,("we have a partner which is neither push nor pull !\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
-}
-
-/****************************************************************************
-initialise and fill the in-memory partner table.
-****************************************************************************/
-int init_wins_partner_table(void)
-{
- int i=1,j=0,k;
- char **partner = str_list_make(lp_wins_partners(), NULL);
-
- if (partner==NULL) {
- DEBUG(0,("wrepld: no partner list in smb.conf, exiting\n"));
- exit_server("normal exit");
- return(0);
- }
-
- DEBUG(4, ("init_wins_partner_table: partners: %s\n", lp_wins_partners()));
-
- global_wins_table[0][0].address=*iface_n_ip(0);
- global_wins_table[0][0].max_version=0;
- global_wins_table[0][0].min_version=0;
- global_wins_table[0][0].type=0;
-
- while (partner[j]!=NULL) {
- DEBUG(3,("init_wins_partner_table, adding partner: %s\n", partner[j]));
-
- global_wins_table[0][i].address=*interpret_addr2(partner[j]);
- global_wins_table[0][i].max_version=0;
- global_wins_table[0][i].min_version=0;
- global_wins_table[0][i].type=0;
- global_wins_table[0][i].last_pull=0;
- global_wins_table[0][i].last_push=0;
-
- i++;
- j++;
- }
-
- for (k=1; k<i;k++)
- for (j=0; j<i; j++)
- global_wins_table[k][j]=global_wins_table[0][j];
-
- str_list_free (&partner);
-
- return i;
-}
-
-/****************************************************************************
-read the last ID from the wins tdb file.
-****************************************************************************/
-static void get_our_last_id(WINS_OWNER *wins_owner)
-{
- TDB_CONTEXT *tdb;
-
- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("get_our_last_id: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return;
- }
-
- wins_owner->max_version=((SMB_BIG_UINT)tdb_fetch_int32(tdb, INFO_ID_HIGH))<<32 |
- (SMB_BIG_UINT)tdb_fetch_int32(tdb, INFO_ID_LOW);
-
- tdb_close(tdb);
-}
-
-/****************************************************************************
-send the list of wins server we know.
-****************************************************************************/
-static void send_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- int i;
- int s_ctx=get_server_assoc(q->header.assoc_ctx);
-
- if (s_ctx==0) {
- DEBUG(5, ("send_version_number_map_table: request for a partner not in our table\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- /*
- * return an array of wins servers, we are partner with.
- * each entry contains the IP address and the version info
- * version: ID of the last entry we've got
- */
-
- /* the first wins server must be self */
-
- /*
- * get our last ID from the wins database
- * it can have been updated since last read
- * as nmbd got registration/release.
- */
- get_our_last_id(&global_wins_table[0][0]);
-
- r->rep.avmt_rep.wins_owner=(WINS_OWNER *)talloc(mem_ctx, partner_count*sizeof(WINS_OWNER));
- if (r->rep.avmt_rep.wins_owner==NULL) {
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- DEBUG(5,("send_version_number_map_table: partner_count: %d\n", partner_count));
-
- for (i=0; i<partner_count; i++) {
- DEBUG(5,("send_version_number_map_table, partner: %d -> %s, \n", i, inet_ntoa(global_wins_table[0][i].address)));
- r->rep.avmt_rep.wins_owner[i]=global_wins_table[0][i];
- }
-
- r->rep.msg_type=1;
- r->rep.avmt_rep.partner_count=partner_count;
- r->rep.avmt_rep.initiating_wins_server.s_addr=0; /* blatant lie, NT4/w2K do the same ! */
- fill_header(r, OPCODE_NON_NBT, s_ctx, MESSAGE_TYPE_REPLICATE);
-}
-
-/****************************************************************************
-for a given partner, ask it to send entries we don't have.
-****************************************************************************/
-static BOOL check_partners_and_send_entries(GENERIC_PACKET *q, GENERIC_PACKET *r, int partner)
-{
- int server;
- int other;
- SMB_BIG_UINT temp;
- SMB_BIG_UINT current;
-
-
- /*
- * we check if our partner has more records than us.
- * we need to check more than our direct partners as
- * we can have this case:
- * us: A, partners: B,C, indirect partner: D
- * A<->B, A<->C, B<->D, C<->D
- *
- * So if we're talking to B, we need to check if between
- * B and C, which one have more records about D.
- * and also check if we don't already have the records.
- */
-
-
- /* check all servers even indirect */
- for (server=1; global_wins_table[0][server].address.s_addr!=0; server++) {
- current = global_wins_table[partner][server].max_version;
-
- temp=0;
-
- for (other=1; other<partner_count; other++) {
- /* skip the partner itself */
- if (other==partner)
- continue;
-
- if (global_wins_table[other][server].max_version > temp)
- temp=global_wins_table[other][server].max_version;
- }
-
- if (current >= temp && current > global_wins_table[0][server].max_version) {
- /*
- * it has more records than every body else and more than us,
- * ask it the difference between what we have and what it has
- */
- fill_header(r, OPCODE_NON_NBT, get_server_assoc(q->header.assoc_ctx), MESSAGE_TYPE_REPLICATE);
-
- r->rep.msg_type=MESSAGE_REP_SEND_ENTRIES_REQUEST;
- r->rep.se_rq.wins_owner.address=global_wins_table[partner][server].address;
-
- r->rep.se_rq.wins_owner.max_version=global_wins_table[partner][server].max_version;
- r->rep.se_rq.wins_owner.min_version=global_wins_table[0][server].max_version;
- r->rep.se_rq.wins_owner.type=0;
-
- write_server_assoc_table(q->header.assoc_ctx, global_wins_table[0][partner].address, global_wins_table[partner][server].address);
-
- /*
- * and we update our version for this server
- * as we can't use the IDs returned in the send_entries function
- * the max ID can be larger than the largest ID returned
- */
-
- global_wins_table[0][server].max_version=global_wins_table[partner][server].max_version;
-
- return True;
- }
- }
- return False;
-}
-
-/****************************************************************************
-receive the list of wins server we know.
-****************************************************************************/
-static void receive_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- fstring peer;
- struct in_addr addr;
- int i,j,k,l;
- int s_ctx=get_server_assoc(q->header.assoc_ctx);
-
- if (s_ctx==0) {
- DEBUG(5, ("receive_version_number_map_table: request for a partner not in our table\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- fstrcpy(peer,get_socket_addr(q->fd));
- addr=*interpret_addr2(peer);
-
- get_our_last_id(&global_wins_table[0][0]);
-
- DEBUG(5,("receive_version_number_map_table: received a map of %d server from: %s\n",
- q->rep.avmt_rep.partner_count ,inet_ntoa(q->rep.avmt_rep.initiating_wins_server)));
- DEBUG(5,("real peer is: %s\n", peer));
-
- for (i=0; global_wins_table[0][i].address.s_addr!=addr.s_addr && i<partner_count;i++)
- ;
-
- if (i==partner_count) {
- DEBUG(5,("receive_version_number_map_table: unknown partner: %s\n", peer));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- for (j=0; j<q->rep.avmt_rep.partner_count;j++) {
- /*
- * search if we already have this entry or if it's a new one
- * it can be a new one in case of propagation
- */
- for (k=0; global_wins_table[0][k].address.s_addr!=0 &&
- global_wins_table[0][k].address.s_addr!=q->rep.avmt_rep.wins_owner[j].address.s_addr; k++);
-
- global_wins_table[i][k].address.s_addr=q->rep.avmt_rep.wins_owner[j].address.s_addr;
- global_wins_table[i][k].max_version=q->rep.avmt_rep.wins_owner[j].max_version;
- global_wins_table[i][k].min_version=q->rep.avmt_rep.wins_owner[j].min_version;
- global_wins_table[i][k].type=q->rep.avmt_rep.wins_owner[j].type;
-
- /*
- * in case it's a new one, rewrite the address for all the partner
- * to reserve the slot.
- */
-
- for(l=0; l<partner_count; l++)
- global_wins_table[l][k].address.s_addr=q->rep.avmt_rep.wins_owner[j].address.s_addr;
- }
-
- dump_global_table();
-
- /*
- * if this server have newer records than what we have
- * for several wins servers, we need to ask it.
- * Alas a send entry request is only on one server.
- * So in the send entry reply, we'll ask for the next server if required.
- */
-
- if (check_partners_and_send_entries(q, r, i))
- return;
-
- /* it doesn't have more entries than us */
- stop_packet(q, r, STOP_REASON_USER_REASON);
-}
-
-/****************************************************************************
-add an entry to the wins list we'll send.
-****************************************************************************/
-static BOOL add_record_to_winsname(WINS_NAME **wins_name, int *max_names, char *name, int type, int wins_flags, int id, struct in_addr *ip_list, int num_ips)
-{
- WINS_NAME *temp_list;
- int i;
- int current=*max_names;
-
- temp_list=talloc_realloc(mem_ctx, *wins_name, (current+1)*sizeof(WINS_NAME));
- if (temp_list==NULL)
- return False;
-
- temp_list[current].name_len=0x11;
-
- safe_strcpy(temp_list[current].name, name, 15);
-
- temp_list[current].type=type;
- temp_list[current].empty=0;
-
- temp_list[current].name_flag=wins_flags;
-
- if ( (wins_flags&0x03) == 1 || (wins_flags&0x03)==2)
- temp_list[current].group_flag=0x01000000;
- else
- temp_list[current].group_flag=0x00000000;
-
- temp_list[current].id=id;
-
- temp_list[current].owner.s_addr=ip_list[0].s_addr;
-
- if (temp_list[current].name_flag & 2) {
- temp_list[current].num_ip=num_ips;
- temp_list[current].others=(struct in_addr *)talloc(mem_ctx, sizeof(struct in_addr)*num_ips);
- if (temp_list[current].others==NULL)
- return False;
-
- for (i=0; i<num_ips; i++)
- temp_list[current].others[i].s_addr=ip_list[i].s_addr;
-
- } else
- temp_list[current].num_ip=1;
-
- temp_list[current].foo=0xffffffff;
-
- *wins_name=temp_list;
-
- return True;
-}
-
-/****************************************************************************
-send the list of name we have.
-****************************************************************************/
-static void send_entry_request(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- int max_names=0;
- int i;
- time_t time_now = time(NULL);
- WINS_OWNER *wins_owner;
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf, newkey;
- int s_ctx=get_server_assoc(q->header.assoc_ctx);
- int num_interfaces = iface_count();
-
- if (s_ctx==0) {
- DEBUG(1, ("send_entry_request: request for a partner not in our table\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
-
- wins_owner=&q->rep.se_rq.wins_owner;
- r->rep.se_rp.wins_name=NULL;
-
- DEBUG(3,("send_entry_request: we have been asked to send the list of wins records\n"));
- DEBUGADD(3,("owned by: %s and between min: %d and max: %d\n", inet_ntoa(wins_owner->address),
- (int)wins_owner->min_version, (int)wins_owner->max_version));
-
- /*
- * if we are asked to send records owned by us
- * we overwrite the wins ip with 0.0.0.0
- * to make it easy in case of multihomed
- */
-
- for (i=0; i<num_interfaces; i++)
- if (ip_equal(wins_owner->address, *iface_n_ip(i))) {
- wins_owner->address=*interpret_addr2("0.0.0.0");
- break;
- }
-
-
- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("send_entry_request: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return;
- }
-
- for (kbuf = tdb_firstkey(tdb);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
- fstring name_type;
- pstring name, ip_str;
- char *p;
- int type = 0;
- int nb_flags;
- int ttl;
- unsigned int num_ips;
- int low, high;
- SMB_BIG_UINT version;
- struct in_addr wins_ip;
- struct in_addr *ip_list;
- int wins_flags;
- int len;
-
- if (strncmp(kbuf.dptr, ENTRY_PREFIX, strlen(ENTRY_PREFIX)) != 0)
- continue;
-
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- continue;
-
- fstrcpy(name_type, kbuf.dptr+strlen(ENTRY_PREFIX));
- pstrcpy(name, name_type);
-
- if((p = strchr(name,'#')) != NULL) {
- *p = 0;
- sscanf(p+1,"%x",&type);
- }
-
- len = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddfddd",
- &nb_flags,
- &high,
- &low,
- ip_str,
- &ttl,
- &num_ips,
- &wins_flags);
-
- wins_ip=*interpret_addr2(ip_str);
-
- /* Allocate the space for the ip_list. */
- if((ip_list = (struct in_addr *)talloc(mem_ctx, num_ips * sizeof(struct in_addr))) == NULL) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("initialise_wins: talloc fail !\n"));
- return;
- }
-
- for (i = 0; i < num_ips; i++) {
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", ip_str);
- ip_list[i] = *interpret_addr2(ip_str);
- }
-
- SAFE_FREE(dbuf.dptr);
-
- /* add all entries that have 60 seconds or more to live */
- if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
- if(ttl != PERMANENT_TTL)
- ttl -= time_now;
-
- DEBUG( 4, ("send_entry_request: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
-
- /* add the record to the list to send */
- version=((SMB_BIG_UINT)high)<<32 | low;
-
- if (wins_owner->min_version<=version && wins_owner->max_version>=version &&
- wins_owner->address.s_addr==wins_ip.s_addr) {
- if(!add_record_to_winsname(&r->rep.se_rp.wins_name, &max_names, name, type, wins_flags, version, ip_list, num_ips))
- return;
- max_names++;
- }
-
- } else {
- DEBUG(4, ("send_entry_request: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
- }
- }
-
- tdb_close(tdb);
-
- DEBUG(4,("send_entry_request, sending %d records\n", max_names));
- fill_header(r, OPCODE_NON_NBT, s_ctx, MESSAGE_TYPE_REPLICATE);
- r->rep.msg_type=MESSAGE_REP_SEND_ENTRIES_REPLY; /* reply */
- r->rep.se_rp.max_names=max_names;
-}
-
-
-/****************************************************************************
-.
-****************************************************************************/
-static void update_notify_request(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- int i,j,k,l;
- UPDATE_NOTIFY_REQUEST *u;
- int s_ctx=get_server_assoc(q->header.assoc_ctx);
-
- if (s_ctx==0) {
- DEBUG(4, ("update_notify_request: request for a partner not in our table\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- u=&q->rep.un_rq;
-
- /* check if we already have the range of records */
-
- DEBUG(5,("update_notify_request: wins server: %s offered this list of %d records:\n",
- inet_ntoa(u->initiating_wins_server), u->partner_count));
-
- get_our_last_id(&global_wins_table[0][0]);
-
- for (i=0; i<partner_count; i++) {
- if (global_wins_table[0][i].address.s_addr==u->initiating_wins_server.s_addr) {
- DEBUG(5,("update_notify_request: found initiator at index %d\n", i));
- break;
- }
- }
-
- /*
- * some explanation is required, before someone say it's crap.
- *
- * let's take an example, we have 2 wins partners, we already now
- * that our max id is 10, partner 1 ID is 20 and partner 2 ID is 30
- * the array looks like:
- *
- * 0 1 2
- * 0 10 20 30
- * 1
- * 2
- *
- * we receive an update from partner 2 saying he has: 1:15, 2:40, 3:50
- * we must enlarge the array to add partner 3, it will look like:
- *
- * 0 1 2 3
- * 0 10 20 30
- * 1
- * 2 15 40 50
- *
- * now we know, we should pull from partner 2, the records 30->40 of 2 and 0->50 of 3.
- * once the pull will be over, our table will look like:
- *
- * 0 1 2 3
- * 0 10 20 40 50
- * 1
- * 2 15 40 50
- *
- *
- */
-
- for (j=0; j<u->partner_count;j++) {
- /*
- * search if we already have this entry or if it's a new one
- * it can be a new one in case of propagation
- */
-
- for (k=0; global_wins_table[0][k].address.s_addr!=0 &&
- global_wins_table[0][k].address.s_addr!=u->wins_owner[j].address.s_addr; k++);
-
- global_wins_table[i][k].address.s_addr=u->wins_owner[j].address.s_addr;
- global_wins_table[i][k].max_version=u->wins_owner[j].max_version;
- global_wins_table[i][k].min_version=u->wins_owner[j].min_version;
- global_wins_table[i][k].type=u->wins_owner[j].type;
-
- /*
- * in case it's a new one, rewrite the address for all the partner
- * to reserve the slot.
- */
-
- for(l=0; l<partner_count; l++)
- global_wins_table[l][k].address.s_addr=u->wins_owner[j].address.s_addr;
- }
-
- dump_global_table();
-
- stop_packet(q, r, STOP_REASON_USER_REASON);
-}
-
-/****************************************************************************
-.
-****************************************************************************/
-static void send_entry_reply(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- int i,j,k;
- struct in_addr partner, server;
- pid_t pid;
- int s_ctx=get_server_assoc(q->header.assoc_ctx);
- WINS_RECORD record;
-
- if (s_ctx==0) {
- DEBUG(1, ("send_entry_reply: request for a partner not in our table\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- DEBUG(5,("send_entry_reply:got %d new records\n", q->rep.se_rp.max_names));
-
- /* we got records from a wins partner but that can be from another wins server */
- /* hopefully we track that */
-
- /* and the only doc available from MS is wrong ! */
-
- get_server_assoc_table(q->header.assoc_ctx, &partner, &server);
-
- for (j=0; global_wins_table[0][j].address.s_addr!=0; j++) {
- if (global_wins_table[0][j].address.s_addr==server.s_addr) {
- DEBUG(5,("send_entry_reply: found server at index %d\n", j));
- break;
- }
- }
-
- pid = pidfile_pid("nmbd");
- if (pid == 0) {
- DEBUG(0,("send_entry_reply: Can't find pid for nmbd\n"));
- return;
- }
-
- for (k=0; k<q->rep.se_rp.max_names; k++) {
- DEBUG(5,("send_entry_reply: %s<%02x> %d\n", q->rep.se_rp.wins_name[k].name, q->rep.se_rp.wins_name[k].type,
- (int)q->rep.se_rp.wins_name[k].id));
-
- safe_strcpy(record.name, q->rep.se_rp.wins_name[k].name, 16);
- record.type=q->rep.se_rp.wins_name[k].type;
- record.id=q->rep.se_rp.wins_name[k].id;
- record.wins_flags=q->rep.se_rp.wins_name[k].name_flag&0x00ff;
- record.num_ips=q->rep.se_rp.wins_name[k].num_ip;
-
- record.wins_ip.s_addr=server.s_addr;
-
- if (record.num_ips==1)
- record.ip[0]=q->rep.se_rp.wins_name[k].owner;
- else
- for (i=0; i<record.num_ips; i++)
- record.ip[i]=q->rep.se_rp.wins_name[k].others[i];
-
- record.nb_flags=0;
-
- if (record.wins_flags&WINS_NGROUP || record.wins_flags&WINS_SGROUP)
- record.nb_flags|=NB_GROUP;
-
- if (record.wins_flags&WINS_ACTIVE)
- record.nb_flags|=NB_ACTIVE;
-
- record.nb_flags|=record.wins_flags&WINS_HNODE;
-
- message_send_pid(pid, MSG_WINS_NEW_ENTRY, &record, sizeof(record), False);
-
- }
-
- dump_global_table();
-
- /*
- * we got some entries,
- * ask the partner to send us the map table again
- * to get the other servers entries.
- *
- * we're getting the map table 1 time more than really
- * required. We could remove that call, but that
- * would complexify the code. I prefer this trade-of.
- */
- fill_header(r, OPCODE_NON_NBT, s_ctx, MESSAGE_TYPE_REPLICATE);
-
- r->rep.msg_type=MESSAGE_REP_ADD_VERSION_REQUEST;
-}
-
-/****************************************************************************
-decode the replication message and reply.
-****************************************************************************/
-static void replicate(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- switch (q->rep.msg_type) {
- case 0:
- /* add version number map table request */
- send_version_number_map_table(q, r);
- break;
- case 1:
- receive_version_number_map_table(q, r);
- break;
- case 2:
- /* send entry request */
- send_entry_request(q, r);
- break;
- case 3:
- /* send entry reply */
- send_entry_reply(q, r);
- break;
- case 4:
- /* update notification request */
- update_notify_request(q, r);
- break;
- }
-}
-
-/****************************************************************************
-do a switch on the message type, and return the response size
-****************************************************************************/
-static BOOL switch_message(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- switch (q->header.mess_type) {
- case 0:
- /* Start association type */
- start_assoc_process(q, r);
- return True;
- break;
- case 1:
- /* start association reply */
- start_assoc_reply(q, r);
- return True;
- break;
- case 2:
- /* stop association message */
- return False;
- break;
- case 3:
- /* replication message */
- replicate(q, r);
- return True;
- break;
- }
-
- return False;
-}
-
-
-/****************************************************************************
- construct a reply to the incoming packet
-****************************************************************************/
-void construct_reply(struct wins_packet_struct *p)
-{
- GENERIC_PACKET r;
- struct BUFFER buffer;
-
- buffer.buffer=NULL;
- buffer.offset=0;
- buffer.length=0;
-
- DEBUG(5,("dump: received packet\n"));
- dump_generic_packet(p->packet);
-
- /* Verify if the request we got is from a listed partner */
- if (!check_partner(p->packet->header.assoc_ctx)) {
- fstring peer;
- struct in_addr addr;
- int i;
- fstrcpy(peer,get_socket_addr(p->fd));
- addr=*interpret_addr2(peer);
-
- for (i=1; i<partner_count; i++)
- if (ip_equal(addr, global_wins_table[0][i].address))
- break;
-
- if (i==partner_count) {
- DEBUG(1,("construct_reply: got a request from a non peer machine: %s\n", peer));
- stop_packet(p->packet, &r, STOP_REASON_AUTH_FAILED);
- p->stop_packet=True;
- encode_generic_packet(&buffer, &r);
- if (!send_smb(p->fd, buffer.buffer))
- exit_server("process_smb: send_smb failed.");
- return;
- }
- }
-
- if (switch_message(p->packet, &r)) {
- encode_generic_packet(&buffer, &r);
- DEBUG(5,("dump: sending packet\n"));
- dump_generic_packet(&r);
-
- if(buffer.offset > 0) {
- if (!send_smb(p->fd, buffer.buffer))
- exit_server("process_smb: send_smb failed.");
- }
- }
-
- /* if we got a stop assoc or if we send a stop assoc, close the fd after */
- if (p->packet->header.mess_type==MESSAGE_TYPE_STOP_ASSOC ||
- r.header.mess_type==MESSAGE_TYPE_STOP_ASSOC) {
- remove_partner(p->packet->header.assoc_ctx);
- p->stop_packet=True;
- }
-}
-
-/****************************************************************************
- contact periodically our wins partner to do a pull replication
-****************************************************************************/
-void run_pull_replication(time_t t)
-{
- /* we pull every 30 minutes to query about new records*/
- int i, s;
- struct BUFFER buffer;
- GENERIC_PACKET p;
-
- buffer.buffer=NULL;
- buffer.offset=0;
- buffer.length=0;
-
- for (i=1; i<partner_count; i++) {
- if (global_wins_table[0][i].last_pull < t) {
- global_wins_table[0][i].last_pull=t+30*60; /* next in 30 minutes */
-
- /* contact the wins server */
- p.header.mess_type=MESSAGE_TYPE_START_ASSOC_REQUEST;
- p.header.opcode=OPCODE_NON_NBT;
- p.header.assoc_ctx=0;
- p.sa_rq.assoc_ctx=(int)t;
- p.sa_rq.min_ver=1;
- p.sa_rq.maj_ver=1;
-
- DEBUG(3,("run_pull_replication: contacting wins server %s.\n", inet_ntoa(global_wins_table[0][i].address)));
- encode_generic_packet(&buffer, &p);
- dump_generic_packet(&p);
-
- /* send the packet to the server and add the descriptor to receive answers */
- s=open_socket_out(SOCK_STREAM, &global_wins_table[0][i].address, 42, LONG_CONNECT_TIMEOUT);
- if (s==-1) {
- DEBUG(0,("run_pull_replication: can't contact wins server %s.\n", inet_ntoa(global_wins_table[0][i].address)));
- return;
- }
-
- if(buffer.offset > 0) {
- if (!send_smb(s, buffer.buffer))
- exit_server("run_pull_replication: send_smb failed.");
- }
-
- add_fd_to_sock_array(s);
- FD_SET(s, listen_set);
-
- /* add ourself as a client */
- add_partner((int)t, 0, True, False);
- }
- }
-}
-
-/****************************************************************************
- contact periodically our wins partner to do a push replication
-****************************************************************************/
-void run_push_replication(time_t t)
-{
- /* we push every 30 minutes or 25 new entries */
- int i, s;
- struct BUFFER buffer;
- GENERIC_PACKET p;
-
- buffer.buffer=NULL;
- buffer.offset=0;
- buffer.length=0;
-
- for (i=1; i<partner_count; i++) {
- if (global_wins_table[0][i].last_pull < t) {
- global_wins_table[0][i].last_pull=t+30*60; /* next in 30 minutes */
-
- /* contact the wins server */
- p.header.mess_type=MESSAGE_TYPE_START_ASSOC_REQUEST;
- p.header.opcode=OPCODE_NON_NBT;
- p.header.assoc_ctx=0;
- p.sa_rq.assoc_ctx=(int)t;
- p.sa_rq.min_ver=1;
- p.sa_rq.maj_ver=1;
-
- DEBUG(3,("run_push_replication: contacting wins server %s.\n", inet_ntoa(global_wins_table[0][i].address)));
- encode_generic_packet(&buffer, &p);
- dump_generic_packet(&p);
-
- /* send the packet to the server and add the descriptor to receive answers */
- s=open_socket_out(SOCK_STREAM, &global_wins_table[0][i].address, 42, LONG_CONNECT_TIMEOUT);
- if (s==-1) {
- DEBUG(0,("run_push_replication: can't contact wins server %s.\n", inet_ntoa(global_wins_table[0][i].address)));
- return;
- }
-
- if(buffer.offset > 0) {
- if (!send_smb(s, buffer.buffer))
- exit_server("run_push_replication: send_smb failed.");
- }
-
- add_fd_to_sock_array(s);
- FD_SET(s, listen_set);
-
- /* add ourself as a client */
- add_partner((int)t, 0, False, True);
- }
- }
-}
-
diff --git a/source4/wrepld/server.c b/source4/wrepld/server.c
deleted file mode 100644
index f49596dc41..0000000000
--- a/source4/wrepld/server.c
+++ /dev/null
@@ -1,737 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Main SMB server routines
- Copyright (C) Jean François Micouleau 1998-2002.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "wins_repl.h"
-
-extern WINS_OWNER *global_wins_table;
-extern int partner_count;
-
-extern fd_set *listen_set;
-extern int listen_number;
-extern int *sock_array;
-
-extern TALLOC_CTX *mem_ctx;
-
-int wins_port = 42;
-
-/****************************************************************************
- when exiting, take the whole family
-****************************************************************************/
-static void *dflt_sig(void)
-{
- exit_server("caught signal");
- return NULL;
-}
-
-/****************************************************************************
- reload the services file
- **************************************************************************/
-BOOL reload_services(BOOL test)
-{
- BOOL ret;
-
- if (lp_loaded()) {
- pstring fname;
- pstrcpy(fname,lp_configfile());
- if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
- pstrcpy(dyn_CONFIGFILE,fname);
- test = False;
- }
- }
-
- reopen_logs();
-
- if (test && !lp_file_list_changed())
- return(True);
-
- ret = lp_load(dyn_CONFIGFILE,False,False,True);
-
-
- /* perhaps the config filename is now set */
- if (!test)
- reload_services(True);
-
- reopen_logs();
-
- load_interfaces();
-
- return(ret);
-}
-
-/****************************************************************************
- Catch a sighup.
-****************************************************************************/
-
-VOLATILE sig_atomic_t reload_after_sighup = False;
-
-static void sig_hup(int sig)
-{
- BlockSignals(True,SIGHUP);
- DEBUG(0,("Got SIGHUP\n"));
-
- sys_select_signal();
- reload_after_sighup = True;
- BlockSignals(False,SIGHUP);
-}
-
-#if DUMP_CORE
-/*******************************************************************
-prepare to dump a core file - carefully!
-********************************************************************/
-static BOOL dump_core(void)
-{
- char *p;
- pstring dname;
- pstrcpy(dname,lp_logfile());
- if ((p=strrchr_m(dname,'/'))) *p=0;
- pstrcat(dname,"/corefiles");
- mkdir(dname,0700);
- sys_chown(dname,getuid(),getgid());
- chmod(dname,0700);
- if (chdir(dname)) return(False);
- umask(~(0700));
-
-#ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_CORE
- {
- struct rlimit rlp;
- getrlimit(RLIMIT_CORE, &rlp);
- rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
- setrlimit(RLIMIT_CORE, &rlp);
- getrlimit(RLIMIT_CORE, &rlp);
- DEBUG(3,("Core limits now %d %d\n",
- (int)rlp.rlim_cur,(int)rlp.rlim_max));
- }
-#endif
-#endif
-
-
- DEBUG(0,("Dumping core in %s\n",dname));
- abort();
- return(True);
-}
-#endif
-
-/****************************************************************************
-exit the server
-****************************************************************************/
-void exit_server(const char *reason)
-{
- static int firsttime=1;
-
- if (!firsttime)
- exit(0);
- firsttime = 0;
-
- DEBUG(2,("Closing connections\n"));
-
- if (!reason) {
- int oldlevel = DEBUGLEVEL;
- DEBUGLEVEL = 10;
- DEBUGLEVEL = oldlevel;
- DEBUG(0,("===============================================================\n"));
-#if DUMP_CORE
- if (dump_core()) return;
-#endif
- }
-
- DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
- exit(0);
-}
-
-/****************************************************************************
- Usage of the program.
-****************************************************************************/
-
-static void usage(char *pname)
-{
-
- d_printf("Usage: %s [-DFSaioPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname);
- d_printf(" [-O socket options] [-s services file]\n");
- d_printf("\t-D Become a daemon (default)\n");
- d_printf("\t-F Run daemon in foreground (for daemontools, etc)\n");
- d_printf("\t-S Log to stdout\n");
- d_printf("\t-a Append to log file (default)\n");
- d_printf("\t-i Run interactive (not a daemon)\n" );
- d_printf("\t-o Overwrite log file, don't append\n");
- d_printf("\t-h Print usage\n");
- d_printf("\t-? Print usage\n");
- d_printf("\t-V Print version\n");
- d_printf("\t-d debuglevel Set the debuglevel\n");
- d_printf("\t-l log basename. Basename for log/debug files\n");
- d_printf("\t-p port Listen on the specified port\n");
- d_printf("\t-O socket options Socket options\n");
- d_printf("\t-s services file. Filename of services file\n");
- d_printf("\n");
-}
-
-/****************************************************************************
- Create an fd_set containing all the sockets in the subnet structures,
- plus the broadcast sockets.
-***************************************************************************/
-
-static BOOL create_listen_fdset(void)
-{
- int i;
- int num_interfaces = iface_count();
- int s;
-
- listen_set = (fd_set *)malloc(sizeof(fd_set));
- if(listen_set == NULL) {
- DEBUG(0,("create_listen_fdset: malloc fail !\n"));
- return True;
- }
-
-#ifdef HAVE_ATEXIT
- {
- static int atexit_set;
- if(atexit_set == 0) {
- atexit_set=1;
- }
- }
-#endif
-
- FD_ZERO(listen_set);
-
- if(lp_interfaces() && lp_bind_interfaces_only()) {
- /* We have been given an interfaces line, and been
- told to only bind to those interfaces. Create a
- socket per interface and bind to only these.
- */
-
- if(num_interfaces > FD_SETSIZE) {
- DEBUG(0,("create_listen_fdset: Too many interfaces specified to bind to. Number was %d max can be %d\n", num_interfaces, FD_SETSIZE));
- return False;
- }
-
- /* Now open a listen socket for each of the interfaces. */
- for(i = 0; i < num_interfaces; i++) {
- struct in_addr *ifip = iface_n_ip(i);
-
- if(ifip == NULL) {
- DEBUG(0,("create_listen_fdset: interface %d has NULL IP address !\n", i));
- continue;
- }
- s = open_socket_in(SOCK_STREAM, wins_port, 0, ifip->s_addr, True);
- if(s == -1)
- return False;
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,lp_socket_options());
-
- if (listen(s, 5) == -1) {
- DEBUG(5,("listen: %s\n",strerror(errno)));
- close(s);
- return False;
- }
- add_fd_to_sock_array(s);
- FD_SET(s, listen_set);
- }
- } else {
- /* Just bind to 0.0.0.0 - accept connections from anywhere. */
- num_interfaces = 1;
-
- /* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, wins_port, 0, interpret_addr(lp_socket_address()),True);
- if (s == -1)
- return(False);
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s, lp_socket_options());
-
- if (listen(s, 5) == -1) {
- DEBUG(0,("create_listen_fdset: listen: %s\n", strerror(errno)));
- close(s);
- return False;
- }
-
- add_fd_to_sock_array(s);
- FD_SET(s, listen_set);
- }
-
- return True;
-}
-
-/*******************************************************************
- read a packet from a socket and parse it, returning a packet ready
- to be used or put on the queue. This assumes a UDP socket
- ******************************************************************/
-static struct wins_packet_struct *read_wins_packet(int fd, int timeout)
-{
- struct wins_packet_struct *p;
- GENERIC_PACKET *q;
- struct BUFFER inbuf;
- ssize_t len=0;
- size_t total=0;
- ssize_t ret;
- BOOL ok = False;
-
- inbuf.buffer=NULL;
- inbuf.length=0;
- inbuf.offset=0;
-
- if(!grow_buffer(&inbuf, 4))
- return NULL;
-
- ok = (read(fd, inbuf.buffer,4) == 4);
- if (!ok)
- return NULL;
- len = smb_len(inbuf.buffer);
-
- if (len<=0)
- return NULL;
-
- if(!grow_buffer(&inbuf, len))
- return NULL;
-
- while (total < len) {
- ret = read(fd, inbuf.buffer + total + 4, len - total);
- if (ret == 0) {
- DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(len - total), strerror(errno) ));
- return NULL;
- }
- if (ret == -1) {
- DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(len - total), strerror(errno) ));
- return NULL;
- }
- total += ret;
- }
-
- q = (GENERIC_PACKET *)talloc(mem_ctx, sizeof(GENERIC_PACKET));
- p = (struct wins_packet_struct *)talloc(mem_ctx, sizeof(*p));
- if (q==NULL || p==NULL)
- return NULL;
-
- decode_generic_packet(&inbuf, q);
-
- q->fd=fd;
-
- p->next = NULL;
- p->prev = NULL;
- p->stop_packet = False;
- p->timestamp = time(NULL);
- p->fd = fd;
- p->packet=q;
-
- return p;
-}
-
-static struct wins_packet_struct *packet_queue = NULL;
-
-/*******************************************************************
- Queue a packet into a packet queue
-******************************************************************/
-static void queue_packet(struct wins_packet_struct *packet)
-{
- struct wins_packet_struct *p;
-
- if (!packet_queue) {
- packet->prev = NULL;
- packet->next = NULL;
- packet_queue = packet;
- return;
- }
-
- /* find the bottom */
- for (p=packet_queue;p->next;p=p->next)
- ;
-
- p->next = packet;
- packet->next = NULL;
- packet->prev = p;
-}
-
-/****************************************************************************
- Listens for NMB or DGRAM packets, and queues them.
- return True if the socket is dead
-***************************************************************************/
-static BOOL listen_for_wins_packets(void)
-{
- int num_interfaces = iface_count();
- fd_set fds;
- int i, num, s, new_s;
- struct timeval timeout;
-
- if(listen_set == NULL) {
- if(!create_listen_fdset()) {
- DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
- return True;
- }
- }
-
- memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
-
- timeout.tv_sec = NMBD_SELECT_LOOP;
- timeout.tv_usec = 0;
-
- /* Prepare for the select - allow certain signals. */
-
- BlockSignals(False, SIGTERM);
-
- num = sys_select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
-
- /* We can only take signals when we are in the select - block them again here. */
-
- BlockSignals(True, SIGTERM);
-
- if(num == -1)
- return False;
-
- for (; num > 0; num--) {
- s = -1;
- /* check the sockets we are only listening on, waiting to accept */
- for (i=0; i<num_interfaces; i++) {
- struct sockaddr addr;
- socklen_t in_addrlen = sizeof(addr);
-
- if(FD_ISSET(sock_array[i], &fds)) {
- s = sock_array[i];
- /* Clear this so we don't look at it again. */
- FD_CLR(sock_array[i], &fds);
-
- /* accept and add the new socket to the listen set */
- new_s=accept(s, &addr, &in_addrlen);
-
- if (new_s < 0)
- continue;
-
- DEBUG(5,("listen_for_wins_packets: new connection, old: %d, new : %d\n", s, new_s));
-
- set_socket_options(new_s, "SO_KEEPALIVE");
- set_socket_options(new_s, lp_socket_options());
- FD_SET(new_s, listen_set);
- add_fd_to_sock_array(new_s);
- }
- }
-
- /*
- * check for the sockets we are waiting data from
- * either client sending datas
- * or reply to our requests
- */
- for (i=num_interfaces; i<listen_number; i++) {
- if(FD_ISSET(sock_array[i], &fds)) {
- struct wins_packet_struct *packet = read_wins_packet(sock_array[i], timeout.tv_sec);
- if (packet) {
- packet->fd = sock_array[i];
- queue_packet(packet);
- }
- DEBUG(2,("listen_for_wins_packets: some data on fd %d\n", sock_array[i]));
- FD_CLR(sock_array[i], &fds);
- break;
- }
-
- }
-
- }
-
- return False;
-}
-
-
-/*******************************************************************
- Run elements off the packet queue till its empty
-******************************************************************/
-
-static void run_wins_packet_queue(void)
-{
- struct wins_packet_struct *p;
-
- while ((p = packet_queue)) {
- packet_queue = p->next;
- if (packet_queue)
- packet_queue->prev = NULL;
- p->next = p->prev = NULL;
-
- construct_reply(p);
-
- /* if it was a stop assoc, close the connection */
- if (p->stop_packet) {
- FD_CLR(p->fd, listen_set);
- remove_fd_from_sock_array(p->fd);
- close(p->fd);
- }
- }
-}
-
-/**************************************************************************** **
- The main select loop.
- **************************************************************************** */
-static void process(void)
-{
-
- while( True ) {
- time_t t = time(NULL);
-
- /* check for internal messages */
- message_dispatch();
-
- if(listen_for_wins_packets())
- return;
-
- run_wins_packet_queue();
-
- run_pull_replication(t);
-
- run_push_replication(t);
-
- /*
- * Reload the services file if we got a sighup.
- */
-
- if(reload_after_sighup) {
- reload_services( True );
- reopen_logs();
- reload_after_sighup = False;
- }
-
- /* free temp memory */
- talloc_destroy_pool(mem_ctx);
-
- /* free up temp memory */
- lp_talloc_free();
- }
-} /* process */
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
- extern char *optarg;
- /* shall I run as a daemon */
- BOOL is_daemon = False;
- BOOL interactive = False;
- BOOL specified_logfile = False;
- BOOL Fork = True;
- BOOL log_stdout = False;
- int opt;
- pstring logfile;
-
-#ifdef HAVE_SET_AUTH_PARAMETERS
- set_auth_parameters(argc,argv);
-#endif
-
- /* this is for people who can't start the program correctly */
- while (argc > 1 && (*argv[1] != '-')) {
- argv++;
- argc--;
- }
-
- while ( EOF != (opt = getopt(argc, argv, "FSO:l:s:d:Dp:h?Vaiof:")) )
- switch (opt) {
- case 'F':
- Fork = False;
- break;
- case 'S':
- log_stdout = True;
- break;
- case 'O':
- lp_set_cmdline("socket options", optarg);
- break;
-
- case 's':
- pstrcpy(dyn_CONFIGFILE,optarg);
- break;
-
- case 'l':
- specified_logfile = True;
- slprintf(logfile, sizeof(logfile)-1, "%s/log.wrepld", optarg);
- lp_set_logfile(logfile);
- break;
-
- case 'i':
- interactive = True;
- Fork = False;
- log_stdout = True;
- break;
-
- case 'D':
- is_daemon = True;
- break;
-
- case 'd':
- if (*optarg == 'A')
- DEBUGLEVEL = 10000;
- else
- DEBUGLEVEL = atoi(optarg);
- break;
-
- case 'p':
- wins_port = atoi(optarg);
- break;
-
- case 'h':
- case '?':
- usage(argv[0]);
- exit(0);
- break;
-
- case 'V':
- d_printf("Version %s\n",VERSION);
- exit(0);
- break;
- default:
- DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
- usage(argv[0]);
- exit(1);
- }
- if (log_stdout && Fork) {
- d_printf("Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n");
- usage(argv[0]);
- exit(1);
- }
-
-#ifdef HAVE_SETLUID
- /* needed for SecureWare on SCO */
- setluid(0);
-#endif
-
- sec_init();
-
- load_case_tables();
-
- if(!specified_logfile) {
- slprintf(logfile, sizeof(logfile)-1, "%s/log.wrepld",
- dyn_LOGFILEBASE);
- lp_set_logfile(logfile);
- }
-
- set_remote_machine_name("wrepld");
-
- setup_logging(argv[0],log_stdout?DEBUG_STDOUT:DEBUG_FILE);
-
- /* we want to re-seed early to prevent time delays causing
- client problems at a later date. (tridge) */
- generate_random_buffer(NULL, 0, False);
-
- /* make absolutely sure we run as root - to handle cases where people
- are crazy enough to have it setuid */
-
- gain_root_privilege();
- gain_root_group_privilege();
-
- fault_setup((void (*)(void *))exit_server);
- CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
-
- /* we are never interested in SIGPIPE */
- BlockSignals(True,SIGPIPE);
-
-#if defined(SIGFPE)
- /* we are never interested in SIGFPE */
- BlockSignals(True,SIGFPE);
-#endif
-
-#if defined(SIGUSR2)
- /* We are no longer interested in USR2 */
- BlockSignals(True,SIGUSR2);
-#endif
-
- /* POSIX demands that signals are inherited. If the invoking process has
- * these signals masked, we will have problems, as we won't recieve them. */
- BlockSignals(False, SIGHUP);
- BlockSignals(False, SIGUSR1);
-
- /* we want total control over the permissions on created files,
- so set our umask to 0 */
- umask(0);
-
- reopen_logs();
-
- DEBUG(1,( "wrepld version %s started.\n", VERSION));
- DEBUGADD(1,( "Copyright Andrew Tridgell and the Samba Team 1992-2002\n"));
-
- DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
- (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
-
- if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
- DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
- exit(1);
- }
-
- /*
- * Do this before reload_services.
- */
-
- if (!reload_services(False))
- return(-1);
-
- if (!init_names())
- return -1;
-
-#ifdef WITH_PROFILE
- if (!profile_setup(False)) {
- DEBUG(0,("ERROR: failed to setup profiling\n"));
- return -1;
- }
-#endif
-
- CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
-
- DEBUG(3,( "loaded services\n"));
-
- if (!is_daemon && !is_a_socket(0)) {
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
- is_daemon = True;
- }
-
- if (is_daemon && !interactive) {
- DEBUG( 3, ( "Becoming a daemon.\n" ) );
- become_daemon(Fork);
- }
-
-#if HAVE_SETPGID
- /*
- * If we're interactive we want to set our own process group for
- * signal management.
- */
- if (interactive)
- setpgid( (pid_t)0, (pid_t)0);
-#endif
-
- if (!directory_exist(lp_lockdir(), NULL)) {
- mkdir(lp_lockdir(), 0755);
- }
-
- if (is_daemon) {
- pidfile_create("wrepld");
- }
-
- if (!message_init()) {
- exit(1);
- }
-
- /* Initialise the memory context */
- mem_ctx=talloc_init("wins repl talloc ctx");
-
- /* initialise the global partners table */
- partner_count=init_wins_partner_table();
-
- /* We can only take signals in the select. */
- BlockSignals( True, SIGTERM );
-
- process();
-
- exit_server("normal exit");
- return(0);
-}
diff --git a/source4/wrepld/socket.c b/source4/wrepld/socket.c
deleted file mode 100644
index 3d759f0ab8..0000000000
--- a/source4/wrepld/socket.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- process incoming packets - main loop
- Copyright (C) Jean François Micouleau 1998-2002.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "wins_repl.h"
-
-fd_set *listen_set = NULL;
-int listen_number = 0;
-int *sock_array = NULL;
-
-/*******************************************************************
- Add an fd from the sock_array
-******************************************************************/
-void add_fd_to_sock_array(int fd)
-{
- int *temp_sock=NULL;
-
- temp_sock=(int *)Realloc(sock_array, (listen_number+1)*sizeof(int));
- if (temp_sock==NULL)
- return;
-
- sock_array=temp_sock;
- sock_array[listen_number]=fd;
- listen_number++;
-}
-
-
-/*******************************************************************
- Remove an fd from the sock_array
-******************************************************************/
-void remove_fd_from_sock_array(int fd)
-{
- int i,j;
-
- for (i=0; sock_array[i]!=fd && i<listen_number; i++)
- ;
-
- if (i==listen_number) {
- DEBUG(0,("remove_fd_from_sock_array: unknown fd: %d\n", fd));
- return;
- }
-
- if (i==listen_number-1) {
- sock_array=(int *)Realloc(sock_array, --listen_number*sizeof(int));
- return;
- }
-
- for (j=i; j<listen_number-1; j++)
- sock_array[j]=sock_array[j+1];
-
- sock_array=(int *)Realloc(sock_array, --listen_number*sizeof(int));
-}
diff --git a/source4/wrepld/wins_repl.h b/source4/wrepld/wins_repl.h
deleted file mode 100644
index 7aa7fa6a9e..0000000000
--- a/source4/wrepld/wins_repl.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Jean François Micouleau 1998-2002.
- *
- * 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.
- */
-
-#define OPCODE_NON_NBT 0x00007800
-
-/* the messages */
-#define MESSAGE_TYPE_START_ASSOC_REQUEST 0
-#define MESSAGE_TYPE_START_ASSOC_REPLY 1
-#define MESSAGE_TYPE_STOP_ASSOC 2
-#define MESSAGE_TYPE_REPLICATE 3
-
-/* the replication sub-message */
-#define MESSAGE_REP_ADD_VERSION_REQUEST 0
-#define MESSAGE_REP_ADD_VERSION_REPLY 1
-#define MESSAGE_REP_SEND_ENTRIES_REQUEST 2
-#define MESSAGE_REP_SEND_ENTRIES_REPLY 3
-#define MESSAGE_REP_UPDATE_NOTIFY_REQUEST 4
-
-/* stop reasons */
-#define STOP_REASON_USER_REASON 0
-#define STOP_REASON_AUTH_FAILED 1
-#define STOP_REASON_INCOMPLETE_VERSION 2
-#define STOP_REASON_BUG_CHECK 3
-#define STOP_REASON_MESSAGE_ERROR 4
-
-
-typedef struct _WINS_OWNER {
- struct in_addr address;
- SMB_BIG_UINT max_version;
- SMB_BIG_UINT min_version;
- int type;
- time_t last_pull;
- time_t last_push;
-} WINS_OWNER;
-
-typedef struct _WINS_NAME {
- int name_len; /* always 0x11 */
- char name[16];
- char type;
- int empty;
- int name_flag;
- int group_flag;
- SMB_BIG_UINT id;
- int num_ip;
- struct in_addr owner;
- struct in_addr *others;
- int foo; /* 0xffffff */
-} WINS_NAME;
-
-typedef struct _WINS_PARTNERS
-{
- int client_assoc;
- int server_assoc;
- BOOL pull_partner;
- BOOL push_partner;
- struct in_addr partner_server;
- struct in_addr other_server;
-} WINS_PARTNER;
-
-typedef struct _generic_header{
- int data_size;
- int opcode;
- int assoc_ctx;
- int mess_type;
-} generic_header;
-
-typedef struct _START_ASSOC_REQUEST {
- int assoc_ctx;
- int min_ver;
- int maj_ver;
-} START_ASSOC_REQUEST;
-
-typedef struct _START_ASSOC_REPLY {
- int assoc_ctx;
- int min_ver;
- int maj_ver;
-} START_ASSOC_REPLY;
-
-typedef struct _STOP_ASSOC {
- int reason;
-} STOP_ASSOC;
-
-typedef struct _AVMT_REP {
- int partner_count;
- WINS_OWNER *wins_owner;
- struct in_addr initiating_wins_server;
-} AVMT_REP;
-
-typedef struct _SEND_ENTRIES_REQUEST {
- WINS_OWNER wins_owner;
-} SEND_ENTRIES_REQUEST;
-
-typedef struct _SEND_ENTRIES_REPLY {
- int max_names;
- WINS_NAME *wins_name;
-} SEND_ENTRIES_REPLY;
-
-typedef struct _UPDATE_NOTIFY_REQUEST {
- int partner_count;
- WINS_OWNER *wins_owner;
- struct in_addr initiating_wins_server;
-} UPDATE_NOTIFY_REQUEST;
-
-typedef struct _REPLICATE {
- int msg_type;
-
- AVMT_REP avmt_rep;
- SEND_ENTRIES_REQUEST se_rq;
- SEND_ENTRIES_REPLY se_rp;
- UPDATE_NOTIFY_REQUEST un_rq;
-} REPLICATE;
-
-
-typedef struct _GENERIC_PACKET {
- int fd;
-
- generic_header header;
-
- START_ASSOC_REQUEST sa_rq;
- START_ASSOC_REPLY sa_rp;
- STOP_ASSOC so;
- REPLICATE rep;
-} GENERIC_PACKET;
-
-struct wins_packet_struct
-{
- struct wins_packet_struct *next;
- struct wins_packet_struct *prev;
- BOOL stop_packet;
- int fd;
- time_t timestamp;
- GENERIC_PACKET *packet;
-};
-
-struct BUFFER {
- char *buffer;
- int offset;
- int length;
-};
-
-
-