From 5ed18fad0037146bb321eb7e73c82be403a45917 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 11 Mar 2010 10:42:18 +1100 Subject: [PATCH 01/16] s4/rpc_server Don't segfault over replPropertyMetaData contents The replPropertyMetaData may contain attrid values that we don't yet have in the local schema. We need to deal with this - it is a serious error, but we should not segfault. Andrew Bartlett --- source4/rpc_server/drsuapi/getncchanges.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 1e407501a58..c7c69de7307 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -175,6 +175,13 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem if (md.ctr.ctr1.array[i].attid == rdn_sa->attributeID_id) continue; sa = dsdb_attribute_by_attributeID_id(schema, md.ctr.ctr1.array[i].attid); + if (!sa) { + DEBUG(0,(__location__ ": Failed to find attribute in schema for attrid %u mentioned in replPropertyMetaData of %s\n", + (unsigned int)md.ctr.ctr1.array[i].attid, + ldb_dn_get_linearized(msg->dn))); + return WERR_DS_DRA_INTERNAL_ERROR; + } + if (sa->linkID) { struct ldb_message_element *el; el = ldb_msg_find_element(msg, sa->lDAPDisplayName); -- 2.11.4.GIT From 4ab3e220c4188b6c147e1a0fa8ce1e2965d74d43 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 9 Mar 2010 23:30:41 +1100 Subject: [PATCH 02/16] Move prototype to header of common code for set_sockaddr_port --- lib/util/util_net.h | 2 ++ source3/include/proto.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/util/util_net.h b/lib/util/util_net.h index 6eacfc395f2..5dc4df5e127 100644 --- a/lib/util/util_net.h +++ b/lib/util/util_net.h @@ -43,4 +43,6 @@ bool interpret_string_addr_prefer_ipv4(struct sockaddr_storage *pss, const char *str, int flags); +void set_sockaddr_port(struct sockaddr *psa, uint16_t port); + #endif /* _SAMBA_UTIL_NET_H_ */ diff --git a/source3/include/proto.h b/source3/include/proto.h index 6ecf0a55423..f6a43852f0d 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1374,7 +1374,6 @@ char *print_sockaddr(char *dest, const struct sockaddr_storage *psa); char *print_canonical_sockaddr(TALLOC_CTX *ctx, const struct sockaddr_storage *pss); -void set_sockaddr_port(struct sockaddr *psa, uint16_t port); const char *client_name(int fd); int get_socket_port(int fd); const char *client_addr(int fd, char *addr, size_t addrlen); -- 2.11.4.GIT From 0201b2fa9f31d8c9a75f3057f91b3f720f62292c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Mar 2010 15:55:26 +1100 Subject: [PATCH 03/16] s4:lib/socket Add function to set a port on the socket address --- source4/lib/socket/socket.c | 12 ++++++++++++ source4/lib/socket/socket.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 30db03fd97c..4b5cecab343 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -25,6 +25,7 @@ #include "system/network.h" #include "param/param.h" #include "../lib/tsocket/tsocket.h" +#include "lib/util/util_net.h" /* auto-close sockets on free @@ -371,6 +372,17 @@ _PUBLIC_ struct tsocket_address *socket_address_to_tsocket_address(TALLOC_CTX *m return r; } +_PUBLIC_ void socket_address_set_port(struct socket_address *a, + uint16_t port) +{ + if (a->sockaddr) { + set_sockaddr_port(a->sockaddr, port); + } else { + a->port = port; + } + +} + _PUBLIC_ struct socket_address *tsocket_address_to_socket_address(TALLOC_CTX *mem_ctx, const struct tsocket_address *a) { diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h index 8f8922bcea4..4a744797b3a 100644 --- a/source4/lib/socket/socket.h +++ b/source4/lib/socket/socket.h @@ -174,6 +174,8 @@ struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx, struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx, struct sockaddr *sockaddr, size_t addrlen); +_PUBLIC_ void socket_address_set_port(struct socket_address *a, + uint16_t port); struct socket_address *socket_address_copy(TALLOC_CTX *mem_ctx, const struct socket_address *oaddr); const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type); -- 2.11.4.GIT From 9457b7ea2214aaa3a466e5dbc2daa0b931975073 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Mar 2010 15:56:13 +1100 Subject: [PATCH 04/16] s4:libcli/resolve Use a more robust way to return the string address By going via these tevent functions, we avoid needing to dereference the struct socket_address, which may contain a 'struct sockaddr' or strings. The new dns_host_file resolver returns in the form of a struct sockaddr. Andrew Bartlett --- source4/libcli/config.mk | 2 +- source4/libcli/resolve/resolve.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 716e23b60d7..246abd414a0 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -65,7 +65,7 @@ LIBCLI_WREPL_OBJ_FILES = $(libclisrcdir)/wrepl/winsrepl.o $(eval $(call proto_header_template,$(libclisrcdir)/wrepl/winsrepl_proto.h,$(LIBCLI_WREPL_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_RESOLVE] -PUBLIC_DEPENDENCIES = NDR_NBT +PUBLIC_DEPENDENCIES = NDR_NBT LIBTSOCKET LIBCLI_RESOLVE_OBJ_FILES = $(libclisrcdir)/resolve/resolve.o diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 0ad3a75e893..77f7f4f46bd 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -27,6 +27,7 @@ #include "system/network.h" #include "lib/socket/socket.h" #include "../lib/util/dlinklist.h" +#include "lib/tsocket/tsocket.h" struct resolve_state { struct resolve_context *ctx; @@ -145,7 +146,7 @@ struct composite_context *resolve_name_all_send(struct resolve_context *ctx, struct composite_context *c; struct resolve_state *state; - if (ctx == NULL || event_ctx == NULL) { + if (event_ctx == NULL) { return NULL; } @@ -239,8 +240,16 @@ NTSTATUS resolve_name_recv(struct composite_context *c, status = resolve_name_all_recv(c, mem_ctx, &addrs, NULL); if (NT_STATUS_IS_OK(status)) { - *reply_addr = talloc_steal(mem_ctx, addrs[0]->addr); + struct tsocket_address *t_addr = socket_address_to_tsocket_address(addrs, addrs[0]); + if (!t_addr) { + return NT_STATUS_NO_MEMORY; + } + + *reply_addr = tsocket_address_inet_addr_string(t_addr, mem_ctx); talloc_free(addrs); + if (!*reply_addr) { + return NT_STATUS_NO_MEMORY; + } } return status; -- 2.11.4.GIT From 79b4a3b22e8a70844b9654f057f6169c553cc809 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Mar 2010 16:04:44 +1100 Subject: [PATCH 05/16] s4:lib/socket Don't go via a string when resolving addresses in connect_multi This also removes the special case for IP addresses, and leaves that to the code in the resolver library. Andrew Bartlett --- source4/lib/socket/connect_multi.c | 48 ++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/source4/lib/socket/connect_multi.c b/source4/lib/socket/connect_multi.c index 68386ba565e..300e5fb1e53 100644 --- a/source4/lib/socket/connect_multi.c +++ b/source4/lib/socket/connect_multi.c @@ -33,7 +33,7 @@ overall state */ struct connect_multi_state { - const char *server_address; + struct socket_address *server_address; int num_ports; uint16_t *ports; @@ -64,7 +64,7 @@ static void continue_one(struct composite_context *creq); */ _PUBLIC_ struct composite_context *socket_connect_multi_send( TALLOC_CTX *mem_ctx, - const char *server_address, + const char *server_name, int num_server_ports, uint16_t *server_ports, struct resolve_context *resolve_ctx, @@ -74,6 +74,9 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send( struct connect_multi_state *multi; int i; + struct nbt_name name; + struct composite_context *creq; + result = talloc_zero(mem_ctx, struct composite_context); if (result == NULL) return NULL; result->state = COMPOSITE_STATE_IN_PROGRESS; @@ -83,9 +86,6 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send( if (composite_nomem(multi, result)) goto failed; result->private_data = multi; - multi->server_address = talloc_strdup(multi, server_address); - if (composite_nomem(multi->server_address, result)) goto failed; - multi->num_ports = num_server_ports; multi->ports = talloc_array(multi, uint16_t, multi->num_ports); if (composite_nomem(multi->ports, result)) goto failed; @@ -94,30 +94,21 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send( multi->ports[i] = server_ports[i]; } - if (!is_ipaddress(server_address)) { - /* - we don't want to do the name resolution separately + /* + we don't want to do the name resolution separately for each port, so start it now, then only start on the real sockets once we have an IP - */ - struct nbt_name name; - struct composite_context *creq; - make_nbt_name_server(&name, server_address); - creq = resolve_name_send(resolve_ctx, multi, &name, result->event_ctx); - if (composite_nomem(creq, result)) goto failed; - composite_continue(result, creq, continue_resolve_name, result); - return result; - } + */ + make_nbt_name_server(&name, server_name); - /* now we've setup the state we can process the first socket */ - connect_multi_next_socket(result); + creq = resolve_name_all_send(resolve_ctx, multi, 0, multi->ports[0], &name, result->event_ctx); + if (composite_nomem(creq, result)) goto failed; - if (!NT_STATUS_IS_OK(result->status)) { - goto failed; - } + composite_continue(result, creq, continue_resolve_name, result); return result; + failed: composite_error(result, result->status); return result; @@ -148,11 +139,11 @@ static void connect_multi_next_socket(struct composite_context *result) result->status = socket_create("ipv4", SOCKET_TYPE_STREAM, &state->sock, 0); if (!composite_is_ok(result)) return; - /* Form up the particular address we are interested in */ - state->addr = socket_address_from_strings(state, state->sock->backend_name, - multi->server_address, multi->ports[next]); + state->addr = socket_address_copy(state, multi->server_address); if (composite_nomem(state->addr, result)) return; + socket_address_set_port(state->addr, multi->ports[next]); + talloc_steal(state, state->sock); creq = socket_connect_send(state->sock, NULL, @@ -197,12 +188,13 @@ static void continue_resolve_name(struct composite_context *creq) struct composite_context); struct connect_multi_state *multi = talloc_get_type(result->private_data, struct connect_multi_state); - const char *addr; + struct socket_address **addr; - result->status = resolve_name_recv(creq, multi, &addr); + result->status = resolve_name_all_recv(creq, multi, &addr, NULL); if (!composite_is_ok(result)) return; - multi->server_address = addr; + /* Let's just go for the first for now */ + multi->server_address = addr[0]; connect_multi_next_socket(result); } -- 2.11.4.GIT From 3723e32e8cca79b52b97d6d6f4cda8ce5ce1bd33 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 9 Mar 2010 23:34:10 +1100 Subject: [PATCH 06/16] s4:samba_dnsupdate Add a 'file based' mode to samba_dnsupdate For the testsuite to use DNS like names, we need to write these names to a file. Also, to have this run in 'make test' the usual rules about 'no 127.*' IP addresses in DNS must be skipped, so glue.interface_ips takes two arguments now --- source4/scripting/bin/samba_dnsupdate | 76 +++++++++++++++++++++-------- source4/scripting/python/pyglue.c | 7 +-- source4/scripting/python/samba/provision.py | 2 +- 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/source4/scripting/bin/samba_dnsupdate b/source4/scripting/bin/samba_dnsupdate index 2e9c469adff..4fdd10de0ac 100755 --- a/source4/scripting/bin/samba_dnsupdate +++ b/source4/scripting/bin/samba_dnsupdate @@ -20,6 +20,7 @@ import getopt import os +import fcntl import sys import tempfile @@ -49,6 +50,8 @@ sambaopts = options.SambaOptions(parser) parser.add_option_group(sambaopts) parser.add_option_group(options.VersionOptions(parser)) parser.add_option("--verbose", action="store_true") +parser.add_option("--all-interfaces", action="store_true") +parser.add_option("--use-file", type="string", help="Use a file, rather than real DNS calls") creds = None ccachename = None @@ -63,7 +66,12 @@ lp = sambaopts.get_loadparm() domain = lp.get("realm") host = lp.get("netbios name") -IPs = glue.interface_ips(lp) +if opts.all_interfaces: + all_interfaces = True +else: + all_interfaces = False + +IPs = glue.interface_ips(lp, all_interfaces) nsupdate_cmd = lp.get('nsupdate command') if len(IPs) == 0: @@ -94,38 +102,37 @@ def get_credentials(lp): ############################################# # an object to hold a parsed DNS line class dnsobj(object): - def __init__(self): - self.type = None - self.name = None + def __init__(self, string_form): + list = string_form.split() self.dest = None self.port = None self.ip = None self.existing_port = None self.existing_weight = None + self.type = list[0] + self.name = list[1] + if self.type == 'SRV': + self.dest = list[2] + self.port = list[3] + elif self.type == 'A': + self.ip = list[2] # usually $IP, which gets replaced + elif self.type == 'CNAME': + self.dest = list[2] + else: + print "Received unexpected DNS reply of type %s" % self.type + raise + def __str__(self): - if d.type == "A": return "%s:%s:%s" % (self.type, self.name, self.ip) - if d.type == "SRV": return "%s:%s:%s:%s" % (self.type, self.name, self.dest, self.port) - if d.type == "CNAME": return "%s:%s:%s" % (self.type, self.name, self.dest) + if d.type == "A": return "%s %s %s" % (self.type, self.name, self.ip) + if d.type == "SRV": return "%s %s %s %s" % (self.type, self.name, self.dest, self.port) + if d.type == "CNAME": return "%s %s %s" % (self.type, self.name, self.dest) ################################################ # parse a DNS line from def parse_dns_line(line, sub_vars): - d = dnsobj() subline = samba.substitute_var(line, sub_vars) - list = subline.split() - d.type = list[0] - d.name = list[1] - if d.type == 'SRV': - d.dest = list[2] - d.port = list[3] - elif d.type == 'A': - d.ip = list[2] # usually $IP, which gets replaced - elif d.type == 'CNAME': - d.dest = list[2] - else: - print "Received unexpected DNS reply of type %s" % d.type - raise + d = dnsobj(subline) return d ############################################ @@ -142,6 +149,24 @@ def check_dns_name(d): normalised_name = d.name.rstrip('.') + '.' if opts.verbose: print "Looking for DNS entry %s as %s" % (d, normalised_name) + + if opts.use_file is not None: + try: + dns_file = open(opts.use_file, "r") + except IOError: + return False + + line = dns_file.readline() + while line: + line = line.rstrip().lstrip() + if line[0] == "#": + line = dns_file.readline() + continue + if line.lower() == str(d).lower(): + return True + line = dns_file.readline() + return False + try: ans = resolver.query(normalised_name, d.type) except resolver.NXDOMAIN: @@ -167,6 +192,7 @@ def check_dns_name(d): d.existing_weight = str(rdata.weight) if opts.verbose: print "Failed to find DNS entry %s" % d + return False @@ -195,6 +221,14 @@ def call_nsupdate(d): if opts.verbose: print "Calling nsupdate for %s" % d + + if opts.use_file is not None: + wfile = open(opts.use_file, 'a') + fcntl.lockf(wfile, fcntl.LOCK_EX) + wfile.write(str(d)+"\n") + fcntl.lockf(wfile, fcntl.LOCK_UN) + return + (tmp_fd, tmpfile) = tempfile.mkstemp() f = os.fdopen(tmp_fd, 'w') if d.type == "A": diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c index 6fe789ae73b..89cf18e16ab 100644 --- a/source4/scripting/python/pyglue.c +++ b/source4/scripting/python/pyglue.c @@ -614,8 +614,9 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args) struct loadparm_context *lp_ctx; struct interface *ifaces; int i, ifcount; + int all_interfaces; - if (!PyArg_ParseTuple(args, "O", &py_lp_ctx)) + if (!PyArg_ParseTuple(args, "Oi", &py_lp_ctx, &all_interfaces)) return NULL; lp_ctx = lp_from_py_object(py_lp_ctx); @@ -633,7 +634,7 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args) /* first count how many are not loopback addresses */ for (ifcount = i = 0; i Date: Tue, 9 Mar 2010 23:29:43 +1100 Subject: [PATCH 07/16] libcli/nbt Add parser for a 'hosts' file that takes DNS record types --- libcli/nbt/config.mk | 1 + libcli/nbt/dns_hosts_file.c | 306 ++++++++++++++++++++++++++++++++++++++++++++ libcli/nbt/libnbt.h | 6 + 3 files changed, 313 insertions(+) create mode 100644 libcli/nbt/dns_hosts_file.c diff --git a/libcli/nbt/config.mk b/libcli/nbt/config.mk index c26118ec50c..14af80e1723 100644 --- a/libcli/nbt/config.mk +++ b/libcli/nbt/config.mk @@ -10,6 +10,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclinbtsrcdir)/, \ lmhosts.o \ + dns_hosts_file.o \ nbtsocket.o \ namequery.o \ nameregister.o \ diff --git a/libcli/nbt/dns_hosts_file.c b/libcli/nbt/dns_hosts_file.c new file mode 100644 index 00000000000..6665a10293d --- /dev/null +++ b/libcli/nbt/dns_hosts_file.c @@ -0,0 +1,306 @@ +/* + Unix SMB/CIFS implementation. + + read a file containing DNS names, types and IP addresses + + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Jeremy Allison 2007 + Copyright (C) Andrew Bartlett 2009. + + 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 3 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, see . +*/ + +/* The purpose of this file is to read the file generated by the samba_dnsupdate script */ + +#include "includes.h" +#include "lib/util/xfile.h" +#include "lib/util/util_net.h" +#include "system/filesys.h" +#include "system/network.h" + +/******************************************************** + Start parsing the dns_hosts_file file. +*********************************************************/ + +static XFILE *startdns_hosts_file(const char *fname) +{ + XFILE *fp = x_fopen(fname,O_RDONLY, 0); + if (!fp) { + DEBUG(4,("startdns_hosts_file: Can't open dns_hosts_file file %s. " + "Error was %s\n", + fname, strerror(errno))); + return NULL; + } + return fp; +} + +/******************************************************** + Parse the next line in the dns_hosts_file file. +*********************************************************/ + +static bool getdns_hosts_fileent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, char **pp_name_type, + char **pp_next_name, + struct sockaddr_storage *pss, uint32_t *p_port) +{ + char line[1024]; + + *pp_name = NULL; + *pp_name_type = NULL; + *pp_next_name = NULL; + *p_port = 0; + + while(!x_feof(fp) && !x_ferror(fp)) { + char *name_type = NULL; + char *name = NULL; + char *next_name = NULL; + char *ip = NULL; + char *port = NULL; + + const char *ptr; + int count = 0; + + if (!fgets_slash(line,sizeof(line),fp)) { + continue; + } + + if (*line == '#') { + continue; + } + + ptr = line; + + if (next_token_talloc(ctx, &ptr, &name_type, NULL)) + ++count; + if (next_token_talloc(ctx, &ptr, &name, NULL)) + ++count; + if (strcasecmp(name_type, "A") == 0) { + if (next_token_talloc(ctx, &ptr, &ip, NULL)) + ++count; + } else if (strcasecmp(name_type, "SRV") == 0) { + if (next_token_talloc(ctx, &ptr, &next_name, NULL)) + ++count; + if (next_token_talloc(ctx, &ptr, &port, NULL)) + ++count; + } else if (strcasecmp(name_type, "CNAME") == 0) { + if (next_token_talloc(ctx, &ptr, &next_name, NULL)) + ++count; + } + if (count <= 0) + continue; + + if (strcasecmp(name_type, "A") == 0) { + if (count != 3) { + DEBUG(0,("getdns_hosts_fileent: Ill formed hosts A record [%s]\n", + line)); + continue; + } + DEBUG(4, ("getdns_hosts_fileent: host entry: %s %s %s\n", + name_type, name, ip)); + if (!interpret_string_addr(pss, ip, AI_NUMERICHOST)) { + DEBUG(0,("getdns_hosts_fileent: invalid address " + "%s.\n", ip)); + } + + } else if (strcasecmp(name_type, "SRV") == 0) { + if (count != 4) { + DEBUG(0,("getdns_hosts_fileent: Ill formed hosts SRV record [%s]\n", + line)); + continue; + } + *p_port = strtoul(port, NULL, 10); + if (*p_port == ULONG_MAX) { + DEBUG(0, ("getdns_hosts_fileent: Ill formed hosts SRV record [%s] (invalid port: %s)\n", + line, port)); + continue; + } + DEBUG(4, ("getdns_hosts_fileent: host entry: %s %s %s %u\n", + name_type, name, next_name, (unsigned int)*p_port)); + *pp_next_name = talloc_strdup(ctx, next_name); + if (!*pp_next_name) { + return false; + } + } else if (strcasecmp(name_type, "CNAME") == 0) { + if (count != 3) { + DEBUG(0,("getdns_hosts_fileent: Ill formed hosts CNAME record [%s]\n", + line)); + continue; + } + DEBUG(4, ("getdns_hosts_fileent: host entry: %s %s %s\n", + name_type, name, next_name)); + *pp_next_name = talloc_strdup(ctx, next_name); + if (!*pp_next_name) { + return false; + } + } else { + DEBUG(0,("getdns_hosts_fileent: unknown type %s\n", name_type)); + continue; + } + + *pp_name = talloc_strdup(ctx, name); + if (!*pp_name) { + return false; + } + + *pp_name_type = talloc_strdup(ctx, name_type); + if (!*pp_name_type) { + return false; + } + return true; + } + + return false; +} + +/******************************************************** + Finish parsing the dns_hosts_file file. +*********************************************************/ + +static void enddns_hosts_file(XFILE *fp) +{ + x_fclose(fp); +} + +/******************************************************** + Resolve via "dns_hosts" method. +*********************************************************/ + +static NTSTATUS resolve_dns_hosts_file_as_sockaddr_recurse(const char *dns_hosts_file, + const char *name, bool srv_lookup, + int level, uint32_t port, + TALLOC_CTX *mem_ctx, + struct sockaddr_storage **return_iplist, + int *return_count) +{ + /* + * "dns_hosts" means parse the local dns_hosts file. + */ + + XFILE *fp; + char *host_name = NULL; + char *name_type = NULL; + char *next_name = NULL; + struct sockaddr_storage return_ss; + uint32_t srv_port; + NTSTATUS status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + TALLOC_CTX *ctx = NULL; + TALLOC_CTX *ip_list_ctx = NULL; + + /* Don't recurse forever, even on our own flat files */ + if (level > 11) { + + } + + *return_iplist = NULL; + *return_count = 0; + + DEBUG(3,("resolve_dns_hosts: " + "Attempting dns_hosts lookup for name %s\n", + name)); + + fp = startdns_hosts_file(dns_hosts_file); + + if ( fp == NULL ) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + + ip_list_ctx = talloc_new(mem_ctx); + if (!ip_list_ctx) { + enddns_hosts_file(fp); + return NT_STATUS_NO_MEMORY; + } + + ctx = talloc_new(ip_list_ctx); + if (!ctx) { + talloc_free(ip_list_ctx); + enddns_hosts_file(fp); + return NT_STATUS_NO_MEMORY; + } + + while (getdns_hosts_fileent(ctx, fp, &host_name, &name_type, &next_name, &return_ss, &srv_port)) { + if (!strequal(name, host_name)) { + TALLOC_FREE(ctx); + ctx = talloc_new(mem_ctx); + if (!ctx) { + enddns_hosts_file(fp); + return NT_STATUS_NO_MEMORY; + } + + continue; + } + + if (srv_lookup) { + if (strcasecmp(name_type, "SRV") == 0) { + /* we only accept one host name per SRV entry */ + enddns_hosts_file(fp); + status = resolve_dns_hosts_file_as_sockaddr_recurse(dns_hosts_file, next_name, + false, + level + 1, srv_port, + mem_ctx, return_iplist, + return_count); + talloc_free(ip_list_ctx); + return status; + } else { + continue; + } + } else if (strcasecmp(name_type, "CNAME") == 0) { + /* we only accept one host name per CNAME */ + enddns_hosts_file(fp); + status = resolve_dns_hosts_file_as_sockaddr_recurse(dns_hosts_file, next_name, false, + level + 1, port, + mem_ctx, return_iplist, return_count); + talloc_free(ip_list_ctx); + return status; + } else if (strcasecmp(name_type, "A") == 0) { + /* Set the specified port (possibly from a SRV lookup) into the structure we return */ + set_sockaddr_port((struct sockaddr *)&return_ss, port); + + /* We are happy to keep looking for other possible A record matches */ + *return_iplist = talloc_realloc(ip_list_ctx, (*return_iplist), + struct sockaddr_storage, + (*return_count)+1); + + if ((*return_iplist) == NULL) { + TALLOC_FREE(ctx); + enddns_hosts_file(fp); + DEBUG(3,("resolve_dns_hosts: talloc_realloc fail !\n")); + return NT_STATUS_NO_MEMORY; + } + + (*return_iplist)[*return_count] = return_ss; + *return_count += 1; + + /* we found something */ + status = NT_STATUS_OK; + } + } + + talloc_steal(mem_ctx, *return_iplist); + TALLOC_FREE(ip_list_ctx); + enddns_hosts_file(fp); + return status; +} + +/******************************************************** + Resolve via "dns_hosts" method. +*********************************************************/ + +NTSTATUS resolve_dns_hosts_file_as_sockaddr(const char *dns_hosts_file, + const char *name, bool srv_lookup, + TALLOC_CTX *mem_ctx, + struct sockaddr_storage **return_iplist, + int *return_count) +{ + return resolve_dns_hosts_file_as_sockaddr_recurse(dns_hosts_file, name, srv_lookup, + 0, 0, + mem_ctx, return_iplist, return_count); +} diff --git a/libcli/nbt/libnbt.h b/libcli/nbt/libnbt.h index 6d6a4a4696b..e150b35566c 100644 --- a/libcli/nbt/libnbt.h +++ b/libcli/nbt/libnbt.h @@ -366,4 +366,10 @@ NTSTATUS resolve_lmhosts_file_as_sockaddr(const char *lmhosts_file, struct sockaddr_storage **return_iplist, int *return_count); +NTSTATUS resolve_dns_hosts_file_as_sockaddr(const char *dns_hosts_file, + const char *name, bool srv_lookup, + TALLOC_CTX *mem_ctx, + struct sockaddr_storage **return_iplist, + int *return_count); + #endif /* __LIBNBT_H__ */ -- 2.11.4.GIT From 1af2cd2bd1c74c88dd00088eb37ad6286af7561f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 24 Feb 2010 22:57:09 +1100 Subject: [PATCH 08/16] s4:libcli/resovle File based lookup module for DNS name types This uses the new common code to read a file containing DNS host names, so we don't have to use real DNS lookups in our test environment. Andrew Bartlett --- source4/libcli/config.mk | 2 +- source4/libcli/resolve/file.c | 150 ++++++++++++++++++++++++++++++++++++ source4/libcli/resolve/resolve_lp.c | 2 + 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 source4/libcli/resolve/file.c diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 246abd414a0..e8741d165a2 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -76,7 +76,7 @@ PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-HOSTCONFIG LIBNETIF LP_RESOLVE_OBJ_FILES = $(addprefix $(libclisrcdir)/resolve/, \ bcast.o nbtlist.o wins.o \ - dns_ex.o \ + dns_ex.o file.o \ host.o resolve_lp.o) $(eval $(call proto_header_template,$(libclisrcdir)/resolve/lp_proto.h,$(LP_RESOLVE_OBJ_FILES:.o=.c))) diff --git a/source4/libcli/resolve/file.c b/source4/libcli/resolve/file.c new file mode 100644 index 00000000000..950815ddc48 --- /dev/null +++ b/source4/libcli/resolve/file.c @@ -0,0 +1,150 @@ +/* + Unix SMB/CIFS implementation. + + broadcast name resolution module + + Copyright (C) Andrew Tridgell 1994-1998,2005 + Copyright (C) Jeremy Allison 2007 + Copyright (C) Jelmer Vernooij 2007 + Copyright (C) Andrew Bartlett 2009-2010 + 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 3 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, see . +*/ + +#include "includes.h" +#include "libcli/composite/composite.h" +#include "libcli/resolve/resolve.h" +#include "lib/socket/socket.h" +#include "system/network.h" +#include "lib/socket/netif.h" +#include "param/param.h" +#include "lib/util/util_net.h" +#include "libcli/nbt/libnbt.h" + +struct resolve_file_data { + const char *lookup_file; +}; + +struct resolve_file_state { + struct socket_address **addrs; + char **names; +}; + +/** + broadcast name resolution method - async send + */ +/* + general name resolution - async send + */ +struct composite_context *resolve_name_file_send(TALLOC_CTX *mem_ctx, + struct tevent_context *event_ctx, + void *userdata, uint32_t flags, + uint16_t port, + struct nbt_name *name) +{ + struct composite_context *c; + struct resolve_file_data *data = talloc_get_type_abort(userdata, struct resolve_file_data); + struct resolve_file_state *state; + struct sockaddr_storage *resolved_iplist; + int resolved_count, i; + + bool srv_lookup = (flags & RESOLVE_NAME_FLAG_DNS_SRV); + + if (event_ctx == NULL) { + return NULL; + } + + c = composite_create(mem_ctx, event_ctx); + if (c == NULL) return NULL; + + /* This isn't an NBT layer resolver */ + if (flags & RESOLVE_NAME_FLAG_FORCE_NBT || name->type != NBT_NAME_SERVER) { + composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND); + return c; + } + + if (composite_nomem(c->event_ctx, c)) return c; + + state = talloc_zero(c, struct resolve_file_state); + if (composite_nomem(state, c)) return c; + c->private_data = state; + + + c->status = resolve_dns_hosts_file_as_sockaddr(data->lookup_file, name->name, srv_lookup, state, &resolved_iplist, &resolved_count); + if (!composite_is_ok(c)) return c; + + for (i=0; i < resolved_count; i++) { + state->addrs = talloc_realloc(state, state->addrs, struct socket_address *, i+2); + if (composite_nomem(state->addrs, c)) return c; + + if (!(flags & RESOLVE_NAME_FLAG_OVERWRITE_PORT)) { + set_sockaddr_port((struct sockaddr *)&resolved_iplist[i], port); + } + + state->addrs[i] = socket_address_from_sockaddr(state->addrs, (struct sockaddr *)&resolved_iplist[i], sizeof(resolved_iplist[i])); + if (composite_nomem(state->addrs[i], c)) return c; + + state->addrs[i+1] = NULL; + + + state->names = talloc_realloc(state, state->names, char *, i+2); + if (composite_nomem(state->addrs, c)) return c; + + state->names[i] = talloc_strdup(state->names, name->name); + if (composite_nomem(state->names[i], c)) return c; + + state->names[i+1] = NULL; + + i++; + } + + composite_done(c); + return c; +} + +/* + general name resolution method - recv side + */ +NTSTATUS resolve_name_file_recv(struct composite_context *c, + TALLOC_CTX *mem_ctx, + struct socket_address ***addrs, + char ***names) +{ + NTSTATUS status; + + status = composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + struct resolve_file_state *state = talloc_get_type(c->private_data, struct resolve_file_state); + *addrs = talloc_steal(mem_ctx, state->addrs); + if (names) { + *names = talloc_steal(mem_ctx, state->names); + } + } + + talloc_free(c); + return status; +} + + +bool resolve_context_add_file_method(struct resolve_context *ctx, const char *lookup_file) +{ + struct resolve_file_data *data = talloc(ctx, struct resolve_file_data); + data->lookup_file = lookup_file; + return resolve_context_add_method(ctx, resolve_name_file_send, resolve_name_file_recv, data); +} + +bool resolve_context_add_file_method_lp(struct resolve_context *ctx, struct loadparm_context *lp_ctx) +{ + return resolve_context_add_file_method(ctx, lp_parm_string(lp_ctx, NULL, "resolv", "host file")); +} diff --git a/source4/libcli/resolve/resolve_lp.c b/source4/libcli/resolve/resolve_lp.c index b41e2b98d86..887e0d543e4 100644 --- a/source4/libcli/resolve/resolve_lp.c +++ b/source4/libcli/resolve/resolve_lp.c @@ -35,6 +35,8 @@ struct resolve_context *lp_resolve_context(struct loadparm_context *lp_ctx) resolve_context_add_wins_method_lp(ret, lp_ctx); } else if (!strcmp(methods[i], "bcast")) { resolve_context_add_bcast_method_lp(ret, lp_ctx); + } else if (!strcmp(methods[i], "file")) { + resolve_context_add_file_method_lp(ret, lp_ctx); } else if (!strcmp(methods[i], "host")) { resolve_context_add_host_method(ret); } else { -- 2.11.4.GIT From e999472e36076e432187371b0853b887effe1067 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Mar 2010 16:01:41 +1100 Subject: [PATCH 09/16] s4:libcli Use integrated name resolution when connecting SMB This avoids pulling the address into a string and back again if given a name, by letting the next async layer down do the name resolution. If it was an IP address to start with, then the resolver library just converts that to the struct socket_address. Andrew Bartlett --- source4/libcli/raw/clisocket.c | 4 +++ source4/libcli/smb_composite/connect.c | 47 +++++++--------------------------- 2 files changed, 13 insertions(+), 38 deletions(-) diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 02da4917e31..84bf250f6a1 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -80,6 +80,10 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, } state->socket_options = talloc_reference(state, socket_options); + if (!host_addr) { + host_addr = host_name; + } + ctx = socket_connect_multi_send(state, host_addr, state->num_ports, state->ports, resolve_ctx, diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 3d35018acbc..14e8a1ab7f7 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -32,8 +32,7 @@ #include "param/param.h" /* the stages of this call */ -enum connect_stage {CONNECT_RESOLVE, - CONNECT_SOCKET, +enum connect_stage {CONNECT_SOCKET, CONNECT_SESSION_REQUEST, CONNECT_NEGPROT, CONNECT_SESSION_SETUP, @@ -362,34 +361,6 @@ static NTSTATUS connect_socket(struct composite_context *c, /* - called when name resolution is finished -*/ -static NTSTATUS connect_resolve(struct composite_context *c, - struct smb_composite_connect *io) -{ - struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); - NTSTATUS status; - const char *address; - - status = resolve_name_recv(state->creq, state, &address); - NT_STATUS_NOT_OK_RETURN(status); - - state->creq = smbcli_sock_connect_send(state, address, - io->in.dest_ports, - io->in.dest_host, - NULL, c->event_ctx, - io->in.socket_options); - NT_STATUS_HAVE_NO_MEMORY(state->creq); - - state->stage = CONNECT_SOCKET; - state->creq->async.private_data = c; - state->creq->async.fn = composite_handler; - - return NT_STATUS_OK; -} - - -/* handle and dispatch state transitions */ static void state_handler(struct composite_context *c) @@ -397,9 +368,6 @@ static void state_handler(struct composite_context *c) struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); switch (state->stage) { - case CONNECT_RESOLVE: - c->status = connect_resolve(c, state->io); - break; case CONNECT_SOCKET: c->status = connect_socket(c, state->io); break; @@ -461,7 +429,6 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec { struct composite_context *c; struct connect_state *state; - struct nbt_name name; c = talloc_zero(mem_ctx, struct composite_context); if (c == NULL) goto failed; @@ -478,11 +445,15 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec c->state = COMPOSITE_STATE_IN_PROGRESS; c->private_data = state; - state->stage = CONNECT_RESOLVE; - make_nbt_name_server(&name, io->in.dest_host); - state->creq = resolve_name_send(resolve_ctx, state, &name, c->event_ctx); - + state->creq = smbcli_sock_connect_send(state, + NULL, + io->in.dest_ports, + io->in.dest_host, + resolve_ctx, c->event_ctx, + io->in.socket_options); if (state->creq == NULL) goto failed; + + state->stage = CONNECT_SOCKET; state->creq->async.private_data = c; state->creq->async.fn = composite_handler; -- 2.11.4.GIT From 59545276f2bd6df8ee5e75e96e707fd86ff44350 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Mar 2010 17:46:09 -0800 Subject: [PATCH 10/16] Try and fix bug #7233 - print fails with jobs >4GB from Win7 clients. Remove an arbitrarty 4G B limit that *doesn't need to be there* ! Jeremy. --- source3/printing/printing.c | 2 +- source3/rpc_server/srv_spoolss_nt.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 50494e37dc9..e48a2d173c8 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2232,7 +2232,7 @@ pause, or resume print job. User name: %s. Printer name: %s.", ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size) { const char* sharename = lp_const_servicename(snum); - int return_code; + ssize_t return_code; struct printjob *pjob; pjob = print_job_find(sharename, jobid); diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index b70376f52aa..a35c5f63828 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -5288,7 +5288,7 @@ WERROR _spoolss_EndDocPrinter(pipes_struct *p, WERROR _spoolss_WritePrinter(pipes_struct *p, struct spoolss_WritePrinter *r) { - uint32_t buffer_written; + ssize_t buffer_written; int snum; Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); @@ -5302,11 +5302,11 @@ WERROR _spoolss_WritePrinter(pipes_struct *p, if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; - buffer_written = (uint32_t)print_job_write(snum, Printer->jobid, + buffer_written = print_job_write(snum, Printer->jobid, (const char *)r->in.data.data, (SMB_OFF_T)-1, (size_t)r->in._data_size); - if (buffer_written == (uint32_t)-1) { + if (buffer_written == (ssize_t)-1) { *r->out.num_written = 0; if (errno == ENOSPC) return WERR_NO_SPOOL_SPACE; -- 2.11.4.GIT From 027123199e13cc02ae4edadd8f0dd0f0660e1193 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 11 Mar 2010 14:49:34 +1100 Subject: [PATCH 11/16] s4:provision Improve the handling of provision errors The backtraces were too confusing for our users, and didn't tell them what to do to fix the problem. By printing the string (rather than a backtrace), and including in the error what to do, and what file to remove, we give them a chance. Andrew Bartlett --- source4/scripting/python/samba/provision.py | 22 ++++++----- .../scripting/python/samba/provisionexceptions.py | 6 ++- source4/setup/provision | 43 +++++++++++++--------- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index bac234cfac6..0a2483790fb 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -330,34 +330,36 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, if dnsdomain is None: dnsdomain = lp.get("realm") if dnsdomain is None or dnsdomain == "": - raise ProvisioningError("guess_names: 'realm' not specified in supplied smb.conf!") + raise ProvisioningError("guess_names: 'realm' not specified in supplied %s!", lp.configfile) dnsdomain = dnsdomain.lower() if serverrole is None: serverrole = lp.get("server role") if serverrole is None: - raise ProvisioningError("guess_names: 'server role' not specified in supplied smb.conf!") + raise ProvisioningError("guess_names: 'server role' not specified in supplied %s!" % lp.configfile) serverrole = serverrole.lower() realm = dnsdomain.upper() + if lp.get("realm") == "": + raise ProvisioningError("guess_names: 'realm =' was not specified in supplied %s. Please remove the smb.conf file and let provision generate it" % lp.configfile) + if lp.get("realm").upper() != realm: - raise ProvisioningError("guess_names: Realm '%s' in smb.conf must match chosen realm '%s'!", lp.get("realm").upper(), realm) + raise ProvisioningError("guess_names: 'realm=%s' in %s must match chosen realm '%s'! Please remove the smb.conf file and let provision generate it" % (lp.get("realm").upper(), realm, lp.configfile)) if lp.get("server role").lower() != serverrole: - raise ProvisioningError("guess_names: server role '%s' in smb.conf must match chosen server role '%s'!", lp.get("server role").upper(), serverrole) + raise ProvisioningError("guess_names: 'server role=%s' in %s must match chosen server role '%s'! Please remove the smb.conf file and let provision generate it" % (lp.get("server role").upper(), serverrole, lp.configfile)) if serverrole == "domain controller": if domain is None: + # This will, for better or worse, default to 'WORKGROUP' domain = lp.get("workgroup") - if domain is None: - raise ProvisioningError("guess_names: 'workgroup' not specified in supplied smb.conf!") domain = domain.upper() if lp.get("workgroup").upper() != domain: - raise ProvisioningError("guess_names: Workgroup '%s' in smb.conf must match chosen domain '%s'!", lp.get("workgroup").upper(), domain) + raise ProvisioningError("guess_names: Workgroup '%s' in %s must match chosen domain '%s'! Please remove the %s file and let provision generate it" % (lp.get("workgroup").upper(), domain, lp.configfile)) if domaindn is None: domaindn = "DC=" + dnsdomain.replace(".", ",DC=") @@ -370,11 +372,11 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, raise InvalidNetbiosName(domain) if hostname.upper() == realm: - raise ProvisioningError("guess_names: Realm '%s' must not be equal to hostname '%s'!", realm, hostname) + raise ProvisioningError("guess_names: Realm '%s' must not be equal to hostname '%s'!" % (realm, hostname)) if netbiosname == realm: - raise ProvisioningError("guess_names: Realm '%s' must not be equal to netbios hostname '%s'!", realm, netbiosname) + raise ProvisioningError("guess_names: Realm '%s' must not be equal to netbios hostname '%s'!" % (realm, netbiosname)) if domain == realm: - raise ProvisioningError("guess_names: Realm '%s' must not be equal to short domain name '%s'!", realm, domain) + raise ProvisioningError("guess_names: Realm '%s' must not be equal to short domain name '%s'!" % (realm, domain)) if rootdn is None: rootdn = domaindn diff --git a/source4/scripting/python/samba/provisionexceptions.py b/source4/scripting/python/samba/provisionexceptions.py index 604853fc198..6159a02e958 100644 --- a/source4/scripting/python/samba/provisionexceptions.py +++ b/source4/scripting/python/samba/provisionexceptions.py @@ -25,8 +25,12 @@ class ProvisioningError(Exception): """A generic provision error.""" + def __init__(self, value): + self.value = value + def __str__(self): + return "ProvisioningError: " + self.value -class InvalidNetbiosName(Exception): +class InvalidNetbiosName(ProvisioningError): """A specified name was not a valid NetBIOS name.""" def __init__(self, name): super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name) diff --git a/source4/setup/provision b/source4/setup/provision index 2b31c4cd567..66aab7ea624 100755 --- a/source4/setup/provision +++ b/source4/setup/provision @@ -37,6 +37,7 @@ from samba.auth import system_session import samba.getopt as options from samba.provision import provision, FILL_FULL, FILL_NT4SYNC, FILL_DRS, find_setup_dir from samba import DS_DOMAIN_FUNCTION_2003, DS_DOMAIN_FUNCTION_2008, DS_DOMAIN_FUNCTION_2008_R2 +from samba.provisionexceptions import ProvisioningError # how do we make this case insensitive?? @@ -225,21 +226,27 @@ elif opts.use_xattrs == "auto": session = system_session() -provision(setup_dir, message, - session, creds, smbconf=smbconf, targetdir=opts.targetdir, - samdb_fill=samdb_fill, realm=opts.realm, domain=opts.domain, - domainguid=opts.domain_guid, domainsid=opts.domain_sid, - policyguid=opts.policy_guid, policyguid_dc=opts.policy_guid_dc, - hostname=opts.host_name, - hostip=opts.host_ip, hostip6=opts.host_ip6, - ntdsguid=opts.ntds_guid, - invocationid=opts.invocationid, adminpass=opts.adminpass, - krbtgtpass=opts.krbtgtpass, machinepass=opts.machinepass, - dnspass=opts.dnspass, root=opts.root, nobody=opts.nobody, - wheel=opts.wheel, users=opts.users, - serverrole=server_role, dom_for_fun_level=dom_for_fun_level, - ldap_backend_extra_port=opts.ldap_backend_extra_port, - backend_type=opts.ldap_backend_type, - ldapadminpass=opts.ldapadminpass, ol_mmr_urls=opts.ol_mmr_urls, - slapd_path=opts.slapd_path, setup_ds_path=opts.setup_ds_path, - nosync=opts.nosync,ldap_dryrun_mode=opts.ldap_dryrun_mode,useeadb=eadb) +try: + provision(setup_dir, message, + session, creds, smbconf=smbconf, targetdir=opts.targetdir, + samdb_fill=samdb_fill, realm=opts.realm, domain=opts.domain, + domainguid=opts.domain_guid, domainsid=opts.domain_sid, + policyguid=opts.policy_guid, policyguid_dc=opts.policy_guid_dc, + hostname=opts.host_name, + hostip=opts.host_ip, hostip6=opts.host_ip6, + ntdsguid=opts.ntds_guid, + invocationid=opts.invocationid, adminpass=opts.adminpass, + krbtgtpass=opts.krbtgtpass, machinepass=opts.machinepass, + dnspass=opts.dnspass, root=opts.root, nobody=opts.nobody, + wheel=opts.wheel, users=opts.users, + serverrole=server_role, dom_for_fun_level=dom_for_fun_level, + ldap_backend_extra_port=opts.ldap_backend_extra_port, + backend_type=opts.ldap_backend_type, + ldapadminpass=opts.ldapadminpass, ol_mmr_urls=opts.ol_mmr_urls, + slapd_path=opts.slapd_path, setup_ds_path=opts.setup_ds_path, + nosync=opts.nosync,ldap_dryrun_mode=opts.ldap_dryrun_mode,useeadb=eadb) +except ProvisioningError as e: + print str(e) + exit(1) + + -- 2.11.4.GIT From ade93755d51e80374e4e6bc6bc501e3230988799 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Tue, 9 Mar 2010 19:12:30 -0600 Subject: [PATCH 12/16] s4:provision - Updated FDS schema mapping. --- source4/setup/schema-map-fedora-ds-1.0 | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/source4/setup/schema-map-fedora-ds-1.0 b/source4/setup/schema-map-fedora-ds-1.0 index 34d48a09626..7dd30502804 100644 --- a/source4/setup/schema-map-fedora-ds-1.0 +++ b/source4/setup/schema-map-fedora-ds-1.0 @@ -41,19 +41,17 @@ sambaConfigOption #This large integer format is unimplemented in OpenLDAP 2.3 1.2.840.113556.1.4.906:1.3.6.1.4.1.1466.115.121.1.27 #This case insensitive string isn't available -1.2.840.113556.1.4.905:1.3.6.1.4.1.1466.115.121.1.15 +1.2.840.113556.1.4.905:1.3.6.1.4.1.1466.115.121.1.44 #Treat Security Descriptors as binary 1.2.840.113556.1.4.907:1.3.6.1.4.1.1466.115.121.1.40 -#NumbericString is not supported in Fedora DS 1.0, map to a directory string -1.3.6.1.4.1.1466.115.121.1.36:1.3.6.1.4.1.1466.115.121.1.15 #Treat Object(DN-Binary) as a binary blob 1.2.840.113556.1.4.903:1.3.6.1.4.1.1466.115.121.1.40 -#Printable String as IA5 String -1.3.6.1.4.1.1466.115.121.1.44:1.3.6.1.4.1.1466.115.121.1.26 #UTC Time as Generalized Time 1.3.6.1.4.1.1466.115.121.1.53:1.3.6.1.4.1.1466.115.121.1.24 #DN with String as Directory String -1.2.840.113556.1.4.904:1.3.6.1.4.1.1466.115.121.1.15 +1.2.840.113556.1.4.904:1.3.6.1.4.1.1466.115.121.1.40 +#attribute names, declared at OIDs fail +1.3.6.1.4.1.1466.115.121.1.38:1.3.6.1.4.1.1466.115.121.1.44 #Presentation Address as Directory String 1.3.6.1.4.1.1466.115.121.1.43:1.3.6.1.4.1.1466.115.121.1.15 -- 2.11.4.GIT From a6253a45c0733e81a8d2200d1d8892383bc00c31 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Wed, 10 Mar 2010 20:34:01 -0600 Subject: [PATCH 13/16] lib/util - Removed curly braces from generate_random_password(). --- lib/util/genrand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/genrand.c b/lib/util/genrand.c index 02b8d8b478d..f8aceae40a4 100644 --- a/lib/util/genrand.c +++ b/lib/util/genrand.c @@ -368,7 +368,7 @@ again: _PUBLIC_ char *generate_random_password(TALLOC_CTX *mem_ctx, size_t min, size_t max) { char *retstr; - const char *c_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,@$%&!?:;<=>(){}[]~"; + const char *c_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,@$%&!?:;<=>()[]~"; size_t len = max; size_t diff; -- 2.11.4.GIT From 6441a5b0b97973b834ba025f1762abe2b5c3f3c9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 11 Mar 2010 15:34:01 +1100 Subject: [PATCH 14/16] Explain why we don't use certain characters in the generated pw --- lib/util/genrand.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/util/genrand.c b/lib/util/genrand.c index f8aceae40a4..7fe55f345ef 100644 --- a/lib/util/genrand.c +++ b/lib/util/genrand.c @@ -368,6 +368,12 @@ again: _PUBLIC_ char *generate_random_password(TALLOC_CTX *mem_ctx, size_t min, size_t max) { char *retstr; + /* This list does not include { or } because they cause + * problems for our provision (it can create a substring + * ${...}, and for Fedora DS (which treats {...} at the start + * of a stored password as special + * -- Andrew Bartlett 2010-03-11 + */ const char *c_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,@$%&!?:;<=>()[]~"; size_t len = max; size_t diff; -- 2.11.4.GIT From cddc542ba5f30316ff4ee8fa591a54808b7be4c8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=BCnther=20Deschner?= Date: Thu, 11 Mar 2010 12:21:08 +0100 Subject: [PATCH 15/16] s3-winreg: Fix _winreg_QueryValue crash bugs and implement windows behavior. Found by RPC-WINREG smbtorture test. Guenther --- source3/rpc_server/srv_winreg_nt.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/source3/rpc_server/srv_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c index 15c79bea46a..5912322d93f 100644 --- a/source3/rpc_server/srv_winreg_nt.c +++ b/source3/rpc_server/srv_winreg_nt.c @@ -230,12 +230,10 @@ WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r) if ( !regkey ) return WERR_BADFID; - if ((r->out.data_length == NULL) || (r->out.type == NULL)) { + if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) { return WERR_INVALID_PARAM; } - *r->out.data_length = *r->out.type = REG_NONE; - DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name)); DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type)); @@ -310,19 +308,18 @@ WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r) *r->out.type = val->type; } - *r->out.data_length = outbuf_size; + status = WERR_BADFILE; - if ( *r->in.data_size == 0 || !r->out.data ) { - status = WERR_OK; - } else if ( *r->out.data_length > *r->in.data_size ) { - status = WERR_MORE_DATA; + if (*r->in.data_size < outbuf_size) { + *r->out.data_size = outbuf_size; + status = r->in.data ? WERR_MORE_DATA : WERR_OK; } else { - memcpy( r->out.data, outbuf, *r->out.data_length ); + *r->out.data_length = outbuf_size; + *r->out.data_size = outbuf_size; + memcpy(r->out.data, outbuf, outbuf_size); status = WERR_OK; } - *r->out.data_size = *r->out.data_length; - if (free_prs) prs_mem_free(&prs_hkpd); if (free_buf) SAFE_FREE(outbuf); -- 2.11.4.GIT From 4d33de545fc80ea300066e9bd7f738ef41c457f7 Mon Sep 17 00:00:00 2001 From: Kamen Mazdrashki Date: Wed, 6 Jan 2010 13:36:27 +0200 Subject: [PATCH 16/16] ECLIPSE + PyDev Project --- source4/.cproject | 224 +++++++++++++++++++++ source4/.project | 83 ++++++++ source4/.pydevproject | 10 + .../org.eclipse.ltk.core.refactoring.prefs | 3 + 4 files changed, 320 insertions(+) create mode 100644 source4/.cproject create mode 100644 source4/.project create mode 100644 source4/.pydevproject create mode 100644 source4/.settings/org.eclipse.ltk.core.refactoring.prefs diff --git a/source4/.cproject b/source4/.cproject new file mode 100644 index 00000000000..d16954b1005 --- /dev/null +++ b/source4/.cproject @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source4/.project b/source4/.project new file mode 100644 index 00000000000..89b3ed75447 --- /dev/null +++ b/source4/.project @@ -0,0 +1,83 @@ + + + samba4 + + + + + + org.python.pydev.PyDevBuilder + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.python.pydev.pythonNature + + diff --git a/source4/.pydevproject b/source4/.pydevproject new file mode 100644 index 00000000000..8a143e4fdde --- /dev/null +++ b/source4/.pydevproject @@ -0,0 +1,10 @@ + + + + +python 2.6 +Default + +/samba4/bin/python + + diff --git a/source4/.settings/org.eclipse.ltk.core.refactoring.prefs b/source4/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 00000000000..af232126eec --- /dev/null +++ b/source4/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,3 @@ +#Mon Aug 17 17:08:04 EEST 2009 +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false -- 2.11.4.GIT