From c624a704be96488f0aee27930cbd4c8d99df464b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 9 Jul 2009 22:03:52 +0200 Subject: Make escape_ldap_string take a talloc context --- source3/include/proto.h | 2 +- source3/lib/ldap_escape.c | 25 +++++++++++++---------- source3/lib/smbldap_util.c | 12 +++++------ source3/libads/ldap_user.c | 6 +++--- source3/passdb/pdb_ldap.c | 45 ++++++++++++++++++++--------------------- source3/utils/net_ads.c | 10 ++++----- source3/winbindd/winbindd_ads.c | 6 +++--- 7 files changed, 54 insertions(+), 52 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index f887b4e796..c0f4dc10d8 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -554,7 +554,7 @@ void init_ldap_debugging(void); /* The following definitions come from lib/ldap_escape.c */ -char *escape_ldap_string_alloc(const char *s); +char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s); char *escape_rdn_val_string_alloc(const char *s); /* The following definitions come from lib/module.c */ diff --git a/source3/lib/ldap_escape.c b/source3/lib/ldap_escape.c index d101bc5ecd..a731cb9864 100644 --- a/source3/lib/ldap_escape.c +++ b/source3/lib/ldap_escape.c @@ -32,10 +32,10 @@ * and to be free()ed by the caller. **/ -char *escape_ldap_string_alloc(const char *s) +char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s) { size_t len = strlen(s)+1; - char *output = (char *)SMB_MALLOC(len); + char *output = talloc_array(mem_ctx, char, len); const char *sub; int i = 0; char *p = output; @@ -43,7 +43,7 @@ char *escape_ldap_string_alloc(const char *s) if (output == NULL) { return NULL; } - + while (*s) { switch (*s) @@ -64,14 +64,17 @@ char *escape_ldap_string_alloc(const char *s) sub = NULL; break; } - + if (sub) { + char *tmp; len = len + 3; - output = (char *)SMB_REALLOC(output, len); - if (!output) { + tmp = talloc_realloc(mem_ctx, output, char, len); + if (tmp == NULL) { + TALLOC_FREE(output); return NULL; } - + output = tmp; + p = &output[i]; strncpy (p, sub, 3); p += 3; @@ -84,7 +87,7 @@ char *escape_ldap_string_alloc(const char *s) } s++; } - + *p = '\0'; return output; } @@ -101,7 +104,7 @@ char *escape_rdn_val_string_alloc(const char *s) } p = output; - + while (*s) { switch (*s) @@ -122,10 +125,10 @@ char *escape_rdn_val_string_alloc(const char *s) *p = *s; p++; } - + s++; } - + *p = '\0'; /* resize the string to the actual final size */ diff --git a/source3/lib/smbldap_util.c b/source3/lib/smbldap_util.c index 66aef6ba66..478a3d24ca 100644 --- a/source3/lib/smbldap_util.c +++ b/source3/lib/smbldap_util.c @@ -126,7 +126,7 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, char *escape_domain_name; /* escape for filter */ - escape_domain_name = escape_ldap_string_alloc(domain_name); + escape_domain_name = escape_ldap_string(talloc_tos(), domain_name); if (!escape_domain_name) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; @@ -135,11 +135,11 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, if (asprintf(&filter, "(&(%s=%s)(objectclass=%s))", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), escape_domain_name, LDAP_OBJ_DOMINFO) < 0) { - SAFE_FREE(escape_domain_name); + TALLOC_FREE(escape_domain_name); return NT_STATUS_NO_MEMORY; } - SAFE_FREE(escape_domain_name); + TALLOC_FREE(escape_domain_name); attr_list = get_attr_list(NULL, dominfo_attr_list ); rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result); @@ -258,7 +258,7 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, int count; char *escape_domain_name; - escape_domain_name = escape_ldap_string_alloc(domain_name); + escape_domain_name = escape_ldap_string(talloc_tos(), domain_name); if (!escape_domain_name) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; @@ -268,11 +268,11 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, LDAP_OBJ_DOMINFO, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), escape_domain_name) < 0) { - SAFE_FREE(escape_domain_name); + TALLOC_FREE(escape_domain_name); return NT_STATUS_NO_MEMORY; } - SAFE_FREE(escape_domain_name); + TALLOC_FREE(escape_domain_name); DEBUG(2, ("smbldap_search_domain_info: Searching for:[%s]\n", filter)); diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index eecd9045e5..69dc05335e 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -30,18 +30,18 @@ ADS_STATUS status; char *ldap_exp; const char *attrs[] = {"*", NULL}; - char *escaped_user = escape_ldap_string_alloc(user); + char *escaped_user = escape_ldap_string(talloc_tos(), user); if (!escaped_user) { return ADS_ERROR(LDAP_NO_MEMORY); } if (asprintf(&ldap_exp, "(samAccountName=%s)", escaped_user) == -1) { - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return ADS_ERROR(LDAP_NO_MEMORY); } status = ads_search(ads, res, ldap_exp, attrs); SAFE_FREE(ldap_exp); - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return status; } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 3579325769..173298561f 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -336,7 +336,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, const char **attr) { char *filter = NULL; - char *escape_user = escape_ldap_string_alloc(user); + char *escape_user = escape_ldap_string(talloc_tos(), user); int ret = -1; if (!escape_user) { @@ -350,7 +350,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)", get_objclass_filter(ldap_state->schema_ver)); if (!filter) { - SAFE_FREE(escape_user); + TALLOC_FREE(escape_user); return LDAP_NO_MEMORY; } /* @@ -360,7 +360,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, filter = talloc_all_string_sub(talloc_tos(), filter, "%u", escape_user); - SAFE_FREE(escape_user); + TALLOC_FREE(escape_user); if (!filter) { return LDAP_NO_MEMORY; } @@ -2120,18 +2120,18 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s /* does the entry already exist but without a samba attributes? we need to return the samba attributes here */ - escape_user = escape_ldap_string_alloc( username ); + escape_user = escape_ldap_string(talloc_tos(), username); filter = talloc_strdup(attr_list, "(uid=%u)"); if (!filter) { status = NT_STATUS_NO_MEMORY; goto fn_exit; } filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user); + TALLOC_FREE(escape_user); if (!filter) { status = NT_STATUS_NO_MEMORY; goto fn_exit; } - SAFE_FREE(escape_user); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr_list, &result); @@ -2278,7 +2278,6 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s fn_exit: TALLOC_FREE(ctx); - SAFE_FREE(escape_user); if (result) { ldap_msgfree(result); } @@ -2528,7 +2527,7 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, const char *name) { char *filter = NULL; - char *escape_name = escape_ldap_string_alloc(name); + char *escape_name = escape_ldap_string(talloc_tos(), name); NTSTATUS status; if (!escape_name) { @@ -2540,11 +2539,11 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name) < 0) { - SAFE_FREE(escape_name); + TALLOC_FREE(escape_name); return NT_STATUS_NO_MEMORY; } - SAFE_FREE(escape_name); + TALLOC_FREE(escape_name); status = ldapsam_getgroup(methods, filter, map); SAFE_FREE(filter); return status; @@ -2665,20 +2664,19 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, for (memberuid = values; *memberuid != NULL; memberuid += 1) { char *escape_memberuid; - escape_memberuid = escape_ldap_string_alloc(*memberuid); + escape_memberuid = escape_ldap_string(talloc_tos(), + *memberuid); if (escape_memberuid == NULL) { ret = NT_STATUS_NO_MEMORY; goto done; } filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid); + TALLOC_FREE(escape_memberuid); if (filter == NULL) { - SAFE_FREE(escape_memberuid); ret = NT_STATUS_NO_MEMORY; goto done; } - - SAFE_FREE(escape_memberuid); } filter = talloc_asprintf_append_buffer(filter, "))"); @@ -2812,7 +2810,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, return NT_STATUS_INVALID_PARAMETER; } - escape_name = escape_ldap_string_alloc(pdb_get_username(user)); + escape_name = escape_ldap_string(talloc_tos(), pdb_get_username(user)); if (escape_name == NULL) return NT_STATUS_NO_MEMORY; @@ -2950,7 +2948,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, done: - SAFE_FREE(escape_name); + TALLOC_FREE(escape_name); return ret; } @@ -4185,14 +4183,14 @@ static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username) goto done; } - escaped = escape_ldap_string_alloc(username); + escaped = escape_ldap_string(talloc_tos(), username); if (escaped == NULL) goto done; result = talloc_string_sub(mem_ctx, filter, "%u", username); done: SAFE_FREE(filter); - SAFE_FREE(escaped); + TALLOC_FREE(escaped); return result; } @@ -4994,10 +4992,10 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, is_machine = True; } - username = escape_ldap_string_alloc(name); + username = escape_ldap_string(talloc_tos(), name); filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))", username, LDAP_OBJ_POSIXACCOUNT); - SAFE_FREE(username); + TALLOC_FREE(username); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -5270,10 +5268,10 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, gid_t gid = -1; int rc; - groupname = escape_ldap_string_alloc(name); + groupname = escape_ldap_string(talloc_tos(), name); filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))", groupname, LDAP_OBJ_POSIXGROUP); - SAFE_FREE(groupname); + TALLOC_FREE(groupname); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -5702,7 +5700,8 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods, return NT_STATUS_NO_MEMORY; } - escape_username = escape_ldap_string_alloc(pdb_get_username(sampass)); + escape_username = escape_ldap_string(talloc_tos(), + pdb_get_username(sampass)); if (escape_username== NULL) { return NT_STATUS_NO_MEMORY; } @@ -5715,7 +5714,7 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods, LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_SAMBASAMACCOUNT); - SAFE_FREE(escape_username); + TALLOC_FREE(escape_username); if (filter == NULL) { return NT_STATUS_NO_MEMORY; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index d82715eb45..f746fc6bd5 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -521,7 +521,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv) return net_ads_user_usage(c, argc, argv); } - escaped_user = escape_ldap_string_alloc(argv[0]); + escaped_user = escape_ldap_string(talloc_tos(), argv[0]); if (!escaped_user) { d_fprintf(stderr, "ads_user_info: failed to escape user %s\n", argv[0]); @@ -529,12 +529,12 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv) } if (!ADS_ERR_OK(ads_startup(c, false, &ads))) { - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return -1; } if (asprintf(&searchstring, "(sAMAccountName=%s)", escaped_user) == -1) { - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return -1; } rc = ads_search(ads, &res, searchstring, attrs); @@ -543,7 +543,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv) if (!ADS_ERR_OK(rc)) { d_fprintf(stderr, "ads_search: %s\n", ads_errstr(rc)); ads_destroy(&ads); - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return -1; } @@ -563,7 +563,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv) ads_msgfree(ads, res); ads_destroy(&ads); - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return 0; } diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index 0f40419a0e..edd70667c0 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -608,7 +608,7 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain, goto done; } - if (!(escaped_dn = escape_ldap_string_alloc(user_dn))) { + if (!(escaped_dn = escape_ldap_string(talloc_tos(), user_dn))) { status = NT_STATUS_NO_MEMORY; goto done; } @@ -620,12 +620,12 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain, GROUP_TYPE_SECURITY_ENABLED); if (!ldap_exp) { DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn)); - SAFE_FREE(escaped_dn); + TALLOC_FREE(escaped_dn); status = NT_STATUS_NO_MEMORY; goto done; } - SAFE_FREE(escaped_dn); + TALLOC_FREE(escaped_dn); rc = ads_search_retry(ads, &res, ldap_exp, group_attrs); -- cgit From f1fad2efe4daf95ad77db6251ad5d77fb9ef755c Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Thu, 9 Jul 2009 15:56:36 -0700 Subject: s3: Fix two arguments that broke when plumbing smb_filneame through dos_mode() --- source3/smbd/dosmode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index ca926aa33c..d3df80ad91 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -448,8 +448,8 @@ static bool get_stat_dos_flags(connection_struct *conn, if (S_ISDIR(smb_fname->st.st_ex_mode)) *dosmode |= aDIR; - *dosmode |= set_sparse_flag(smb_fname->st); - *dosmode |= set_link_read_only_flag(smb_fname->st); + *dosmode |= set_sparse_flag(&smb_fname->st); + *dosmode |= set_link_read_only_flag(&smb_fname->st); return true; } -- cgit From 8d1b061b517176e172151e6814083aa7a7051d56 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 9 Jul 2009 21:04:08 -0400 Subject: cifs.upcall: use pid value from kernel to determine KRB5CCNAME to use If the kernel sends the upcall a pid of the requesting process, we can open that process' /proc//environ file and scrape the KRB5CCNAME value out of it. Signed-off-by: Jeff Layton --- client/cifs.upcall.c | 87 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 12 deletions(-) diff --git a/client/cifs.upcall.c b/client/cifs.upcall.c index 4110de35fd..e592a4f7c5 100644 --- a/client/cifs.upcall.c +++ b/client/cifs.upcall.c @@ -1,6 +1,7 @@ /* * CIFS user-space helper. * Copyright (C) Igor Mammedov (niallain@gmail.com) 2007 +* Copyright (C) Jeff Layton (jlayton@redhat.com) 2009 * * Used by /sbin/request-key for handling * cifs upcall for kerberos authorization of access to share and @@ -37,6 +38,54 @@ typedef enum _secType { MS_KRB5 } secType_t; +/* + * given a process ID, get the value of the KRB5CCNAME environment variable + * in the context of that process. On error, just return NULL. + */ +static char * +get_krb5_ccname(pid_t pid) +{ + int fd; + ssize_t len, left; + + /* + * FIXME: sysconf for ARG_MAX instead? Kernel seems to be limited to a + * page however, so it may not matter. + */ + char buf[4096]; + char *p, *value = NULL; + + buf[4095] = '\0'; + snprintf(buf, 4095, "/proc/%d/environ", pid); + fd = open(buf, O_RDONLY); + if (fd < 0) + return NULL; + + /* FIXME: don't assume that we get it all in the first read? */ + len = read(fd, buf, 4096); + close(fd); + if (len < 0) + return NULL; + + left = len; + p = buf; + + /* can't have valid KRB5CCNAME if there are < 13 bytes left */ + while (left > 12) { + if (strncmp("KRB5CCNAME=", p, 11)) { + p += strnlen(p, left); + ++p; + left = buf + len - p; + continue; + } + p += 11; + left -= 11; + value = strndup(p, left); + break; + } + return value; +} + /* * Prepares AP-REQ data for mechToken and gets session key * Uses credentials from cache. It will not ask for password @@ -58,15 +107,15 @@ typedef enum _secType { * ret: 0 - success, others - failure */ static int -handle_krb5_mech(const char *oid, const char *principal, - DATA_BLOB * secblob, DATA_BLOB * sess_key) +handle_krb5_mech(const char *oid, const char *principal, DATA_BLOB *secblob, + DATA_BLOB *sess_key, const char *ccname) { int retval; DATA_BLOB tkt, tkt_wrapped; /* get a kerberos ticket for the service and extract the session key */ - retval = cli_krb5_get_ticket(principal, 0, - &tkt, sess_key, 0, NULL, NULL); + retval = cli_krb5_get_ticket(principal, 0, &tkt, sess_key, 0, ccname, + NULL); if (retval) return retval; @@ -88,11 +137,12 @@ handle_krb5_mech(const char *oid, const char *principal, #define DKD_HAVE_IPV4 8 #define DKD_HAVE_IPV6 16 #define DKD_HAVE_UID 32 +#define DKD_HAVE_PID 64 #define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC) static int -decode_key_description(const char *desc, int *ver, secType_t * sec, - char **hostname, uid_t * uid) +decode_key_description(const char *desc, int *ver, secType_t *sec, + char **hostname, uid_t *uid, pid_t *pid) { int retval = 0; char *pos; @@ -117,6 +167,16 @@ decode_key_description(const char *desc, int *ver, secType_t * sec, /* BB: do we need it if we have hostname already? */ } else if (strncmp(tkn, "ipv6=", 5) == 0) { /* BB: do we need it if we have hostname already? */ + } else if (strncmp(tkn, "pid=", 4) == 0) { + errno = 0; + *pid = strtol(tkn + 4, NULL, 0); + if (errno != 0) { + syslog(LOG_WARNING, "Invalid pid format: %s", + strerror(errno)); + return 1; + } else { + retval |= DKD_HAVE_PID; + } } else if (strncmp(tkn, "sec=", 4) == 0) { if (strncmp(tkn + 4, "krb5", 4) == 0) { retval |= DKD_HAVE_SEC; @@ -224,9 +284,10 @@ int main(const int argc, char *const argv[]) size_t datalen; long rc = 1; uid_t uid = 0; + pid_t pid = 0; int kernel_upcall_version = 0; int c, use_cifs_service_prefix = 0; - char *buf, *hostname = NULL; + char *buf, *ccname = NULL, *hostname = NULL; const char *oid; openlog(prog, 0, LOG_DAEMON); @@ -278,7 +339,7 @@ int main(const int argc, char *const argv[]) } rc = decode_key_description(buf, &kernel_upcall_version, §ype, - &hostname, &uid); + &hostname, &uid, &pid); if ((rc & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) { syslog(LOG_WARNING, "unable to get from description necessary params"); @@ -296,6 +357,9 @@ int main(const int argc, char *const argv[]) goto out; } + if (rc & DKD_HAVE_PID) + ccname = get_krb5_ccname(pid); + if (rc & DKD_HAVE_UID) { rc = setuid(uid); if (rc == -1) { @@ -304,9 +368,6 @@ int main(const int argc, char *const argv[]) } } - /* BB: someday upcall SPNEGO blob could be checked here to decide - * what mech to use */ - // do mech specific authorization switch (sectype) { case MS_KRB5: @@ -333,7 +394,8 @@ int main(const int argc, char *const argv[]) else oid = OID_KERBEROS5; - rc = handle_krb5_mech(oid, princ, &secblob, &sess_key); + rc = handle_krb5_mech(oid, princ, &secblob, &sess_key, + ccname); SAFE_FREE(princ); break; } @@ -385,6 +447,7 @@ out: keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT); data_blob_free(&secblob); data_blob_free(&sess_key); + SAFE_FREE(ccname); SAFE_FREE(hostname); SAFE_FREE(keydata); return rc; -- cgit From db1e58256861c50a9baed8efc862ba5b5834e28b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 11:59:00 +0200 Subject: Attempt to fix the build -- jlayton, please check! --- client/cifs.upcall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cifs.upcall.c b/client/cifs.upcall.c index e592a4f7c5..82b9f7b91b 100644 --- a/client/cifs.upcall.c +++ b/client/cifs.upcall.c @@ -80,7 +80,7 @@ get_krb5_ccname(pid_t pid) } p += 11; left -= 11; - value = strndup(p, left); + value = SMB_STRNDUP(p, left); break; } return value; -- cgit From 12ed9ca36a4f8d2f3798f357a619389c26c9feea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2009 17:02:00 +0200 Subject: s3:smbd: fix parsing of invalid SMB2 requests. Because of 0 - 2 => 0xFFFFFFFE, we got EMSGSIZE from the tstream layer. And terminate the transport connection. Instead we should let the caller deal with the invalid parameter, when checking the body size. So the caller always gets at least a 2 byte body. metze --- source3/smbd/smb2_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 43afb1b901..204e57d860 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -1339,7 +1339,7 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream, if (invalid) { /* the caller should check this */ - body_size = 0; + body_size = 2; } if ((body_size % 2) != 0) { @@ -1376,7 +1376,7 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream, */ memcpy(body, hdr + SMB2_HDR_BODY, 2); vector[0].iov_base = body + 2; - vector[0].iov_len = req->in.vector[idx].iov_len - 2; + vector[0].iov_len = body_size - 2; vector[1] = req->in.vector[idx+1]; -- cgit From 24c8e786bcdf2d10e378b655e1df69c2533f7804 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jul 2009 11:33:58 +0200 Subject: s3:smbd: fix parsing of SMB2 Lock requests with lock_count > 1 We should not reuse the variable 'i'. metze --- source3/smbd/smb2_lock.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 3ffe053481..da57181e86 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -41,7 +41,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) { const uint8_t *inhdr; const uint8_t *inbody; - int i = req->current_idx; + const int i = req->current_idx; size_t expected_body_size = 0x30; size_t body_size; uint16_t in_lock_count; @@ -50,6 +50,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) struct smbd_smb2_lock_element *in_locks; struct tevent_req *subreq; const uint8_t *lock_buffer; + uint16_t l; inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { @@ -64,7 +65,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) } in_lock_count = CVAL(inbody, 0x02); - /* 0x04 4 bytes reserved */ + /* 0x04 - 4 bytes reserved */ in_file_id_persistent = BVAL(inbody, 0x08); in_file_id_volatile = BVAL(inbody, 0x10); @@ -88,19 +89,21 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); } - i = 0; + l = 0; lock_buffer = inbody + 0x18; - in_locks[i].offset = BVAL(lock_buffer, 0x00); - in_locks[i].length = BVAL(lock_buffer, 0x08); - in_locks[i].flags = BVAL(lock_buffer, 0x10); + in_locks[l].offset = BVAL(lock_buffer, 0x00); + in_locks[l].length = BVAL(lock_buffer, 0x08); + in_locks[l].flags = IVAL(lock_buffer, 0x10); + /* 0x14 - 4 reserved bytes */ lock_buffer = (const uint8_t *)req->in.vector[i+2].iov_base; - for (i=1; i < in_lock_count; i++) { - in_locks[i].offset = BVAL(lock_buffer, 0x00); - in_locks[i].length = BVAL(lock_buffer, 0x08); - in_locks[i].flags = BVAL(lock_buffer, 0x10); + for (l=1; l < in_lock_count; l++) { + in_locks[l].offset = BVAL(lock_buffer, 0x00); + in_locks[l].length = BVAL(lock_buffer, 0x08); + in_locks[l].flags = IVAL(lock_buffer, 0x10); + /* 0x14 - 4 reserved bytes */ lock_buffer += 0x18; } -- cgit From be1e5493c5aa323681d2843f37e93a0388e95f6a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jul 2009 11:34:14 +0200 Subject: s3:smbd: pass down the client pid to smbd_smb2_lock_send() metze --- source3/smbd/smb2_lock.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index da57181e86..06e97b97b0 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -31,6 +31,7 @@ struct smbd_smb2_lock_element { static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct smbd_smb2_request *smb2req, + uint32_t in_smbpid, uint64_t in_file_id_volatile, uint16_t in_lock_count, struct smbd_smb2_lock_element *in_locks); @@ -44,6 +45,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) const int i = req->current_idx; size_t expected_body_size = 0x30; size_t body_size; + uint32_t in_smbpid; uint16_t in_lock_count; uint64_t in_file_id_persistent; uint64_t in_file_id_volatile; @@ -64,6 +66,8 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } + in_smbpid = IVAL(inhdr, SMB2_HDR_PID); + in_lock_count = CVAL(inbody, 0x02); /* 0x04 - 4 bytes reserved */ in_file_id_persistent = BVAL(inbody, 0x08); @@ -111,6 +115,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) subreq = smbd_smb2_lock_send(req, req->conn->smb2.event_ctx, req, + in_smbpid, in_file_id_volatile, in_lock_count, in_locks); @@ -175,6 +180,7 @@ struct smbd_smb2_lock_state { static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct smbd_smb2_request *smb2req, + uint32_t in_smbpid, uint64_t in_file_id_volatile, uint16_t in_lock_count, struct smbd_smb2_lock_element *in_locks) -- cgit From 598a9892bc4d5db2c75b218ba235fb7736b6a6e6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2009 17:24:25 +0200 Subject: s3:smbd: abstract the main locking logic from the LockingAndX parsing This prepares SMB2 Lock support. metze --- source3/smbd/reply.c | 432 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 254 insertions(+), 178 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 1fd4e50ea6..4a915d6f90 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -7223,6 +7223,212 @@ uint64_t get_lock_offset(const uint8_t *data, int data_offset, return offset; } +struct smbd_lock_element { + uint32_t smbpid; + enum brl_type brltype; + uint64_t offset; + uint64_t count; +}; + +static NTSTATUS smbd_do_locking(struct smb_request *req, + files_struct *fsp, + uint8_t type, + int32_t timeout, + uint16_t num_ulocks, + struct smbd_lock_element *ulocks, + uint16_t num_locks, + struct smbd_lock_element *locks, + bool *async) +{ + connection_struct *conn = req->conn; + int i; + NTSTATUS status = NT_STATUS_OK; + + *async = false; + + /* Data now points at the beginning of the list + of smb_unlkrng structs */ + for(i = 0; i < (int)num_ulocks; i++) { + struct smbd_lock_element *e = &ulocks[i]; + + DEBUG(10,("smbd_do_locking: unlock start=%.0f, len=%.0f for " + "pid %u, file %s\n", + (double)e->offset, + (double)e->count, + (unsigned int)e->smbpid, + fsp->fsp_name)); + + if (e->brltype != UNLOCK_LOCK) { + /* this can only happen with SMB2 */ + return NT_STATUS_INVALID_PARAMETER; + } + + status = do_unlock(smbd_messaging_context(), + fsp, + e->smbpid, + e->count, + e->offset, + WINDOWS_LOCK); + + DEBUG(10, ("smbd_do_locking: unlock returned %s\n", + nt_errstr(status))); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + /* Setup the timeout in seconds. */ + + if (!lp_blocking_locks(SNUM(conn))) { + timeout = 0; + } + + /* Data now points at the beginning of the list + of smb_lkrng structs */ + + for(i = 0; i < (int)num_locks; i++) { + struct smbd_lock_element *e = &locks[i]; + + DEBUG(10,("smbd_do_locking: lock start=%.0f, len=%.0f for pid " + "%u, file %s timeout = %d\n", + (double)e->offset, + (double)e->count, + (unsigned int)e->smbpid, + fsp->fsp_name, + (int)timeout)); + + if (type & LOCKING_ANDX_CANCEL_LOCK) { + struct blocking_lock_record *blr = NULL; + + if (lp_blocking_locks(SNUM(conn))) { + + /* Schedule a message to ourselves to + remove the blocking lock record and + return the right error. */ + + blr = blocking_lock_cancel(fsp, + e->smbpid, + e->offset, + e->count, + WINDOWS_LOCK, + type, + NT_STATUS_FILE_LOCK_CONFLICT); + if (blr == NULL) { + return NT_STATUS_DOS( + ERRDOS, + ERRcancelviolation); + } + } + /* Remove a matching pending lock. */ + status = do_lock_cancel(fsp, + e->smbpid, + e->count, + e->offset, + WINDOWS_LOCK, + blr); + } else { + bool blocking_lock = timeout ? true : false; + bool defer_lock = false; + struct byte_range_lock *br_lck; + uint32_t block_smbpid; + + br_lck = do_lock(smbd_messaging_context(), + fsp, + e->smbpid, + e->count, + e->offset, + e->brltype, + WINDOWS_LOCK, + blocking_lock, + &status, + &block_smbpid, + NULL); + + if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) { + /* Windows internal resolution for blocking locks seems + to be about 200ms... Don't wait for less than that. JRA. */ + if (timeout != -1 && timeout < lp_lock_spin_time()) { + timeout = lp_lock_spin_time(); + } + defer_lock = true; + } + + /* This heuristic seems to match W2K3 very well. If a + lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT + it pretends we asked for a timeout of between 150 - 300 milliseconds as + far as I can tell. Replacement for do_lock_spin(). JRA. */ + + if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock && + NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) { + defer_lock = true; + timeout = lp_lock_spin_time(); + } + + if (br_lck && defer_lock) { + /* + * A blocking lock was requested. Package up + * this smb into a queued request and push it + * onto the blocking lock queue. + */ + if(push_blocking_lock_request(br_lck, + req, + fsp, + timeout, + i, + e->smbpid, + e->brltype, + WINDOWS_LOCK, + e->offset, + e->count, + block_smbpid)) { + TALLOC_FREE(br_lck); + *async = true; + return NT_STATUS_OK; + } + } + + TALLOC_FREE(br_lck); + } + + if (!NT_STATUS_IS_OK(status)) { + break; + } + } + + /* If any of the above locks failed, then we must unlock + all of the previous locks (X/Open spec). */ + + if (num_locks != 0 && !NT_STATUS_IS_OK(status)) { + + if (type & LOCKING_ANDX_CANCEL_LOCK) { + i = -1; /* we want to skip the for loop */ + } + + /* + * Ensure we don't do a remove on the lock that just failed, + * as under POSIX rules, if we have a lock already there, we + * will delete it (and we shouldn't) ..... + */ + for(i--; i >= 0; i--) { + struct smbd_lock_element *e = &locks[i]; + + do_unlock(smbd_messaging_context(), + fsp, + e->smbpid, + e->count, + e->offset, + WINDOWS_LOCK); + } + return status; + } + + DEBUG(3, ("smbd_do_locking: fnum=%d type=%d num_locks=%d num_ulocks=%d\n", + fsp->fnum, (unsigned int)type, num_locks, num_ulocks)); + + return NT_STATUS_OK; +} + /**************************************************************************** Reply to a lockingX request. ****************************************************************************/ @@ -7235,14 +7441,15 @@ void reply_lockingX(struct smb_request *req) unsigned char oplocklevel; uint16 num_ulocks; uint16 num_locks; - uint64_t count = 0, offset = 0; - uint32 lock_pid; int32 lock_timeout; int i; const uint8_t *data; bool large_file_format; bool err; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + struct smbd_lock_element *ulocks; + struct smbd_lock_element *locks; + bool async = false; START_PROFILE(SMBlockingX); @@ -7355,12 +7562,27 @@ void reply_lockingX(struct smb_request *req) return; } + ulocks = talloc_array(req, struct smbd_lock_element, num_ulocks); + if (ulocks == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + END_PROFILE(SMBlockingX); + return; + } + + locks = talloc_array(req, struct smbd_lock_element, num_locks); + if (locks == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + END_PROFILE(SMBlockingX); + return; + } + /* Data now points at the beginning of the list of smb_unlkrng structs */ for(i = 0; i < (int)num_ulocks; i++) { - lock_pid = get_lock_pid( data, i, large_file_format); - count = get_lock_count( data, i, large_file_format); - offset = get_lock_offset( data, i, large_file_format, &err); + ulocks[i].smbpid = get_lock_pid(data, i, large_file_format); + ulocks[i].count = get_lock_count(data, i, large_file_format); + ulocks[i].offset = get_lock_offset(data, i, large_file_format, &err); + ulocks[i].brltype = UNLOCK_LOCK; /* * There is no error code marked "stupid client bug".... :-). @@ -7370,32 +7592,6 @@ void reply_lockingX(struct smb_request *req) reply_doserror(req, ERRDOS, ERRnoaccess); return; } - - DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for " - "pid %u, file %s\n", (double)offset, (double)count, - (unsigned int)lock_pid, fsp->fsp_name )); - - status = do_unlock(smbd_messaging_context(), - fsp, - lock_pid, - count, - offset, - WINDOWS_LOCK); - - DEBUG(10, ("reply_lockingX: unlock returned %s\n", - nt_errstr(status))); - - if (NT_STATUS_V(status)) { - END_PROFILE(SMBlockingX); - reply_nterror(req, status); - return; - } - } - - /* Setup the timeout in seconds. */ - - if (!lp_blocking_locks(SNUM(conn))) { - lock_timeout = 0; } /* Now do any requested locks */ @@ -7405,11 +7601,23 @@ void reply_lockingX(struct smb_request *req) of smb_lkrng structs */ for(i = 0; i < (int)num_locks; i++) { - enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ? - READ_LOCK:WRITE_LOCK); - lock_pid = get_lock_pid( data, i, large_file_format); - count = get_lock_count( data, i, large_file_format); - offset = get_lock_offset( data, i, large_file_format, &err); + locks[i].smbpid = get_lock_pid(data, i, large_file_format); + locks[i].count = get_lock_count(data, i, large_file_format); + locks[i].offset = get_lock_offset(data, i, large_file_format, &err); + + if (locktype & LOCKING_ANDX_SHARED_LOCK) { + if (locktype & LOCKING_ANDX_CANCEL_LOCK) { + locks[i].brltype = PENDING_READ_LOCK; + } else { + locks[i].brltype = READ_LOCK; + } + } else { + if (locktype & LOCKING_ANDX_CANCEL_LOCK) { + locks[i].brltype = PENDING_WRITE_LOCK; + } else { + locks[i].brltype = WRITE_LOCK; + } + } /* * There is no error code marked "stupid client bug".... :-). @@ -7419,154 +7627,22 @@ void reply_lockingX(struct smb_request *req) reply_doserror(req, ERRDOS, ERRnoaccess); return; } - - DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid " - "%u, file %s timeout = %d\n", (double)offset, - (double)count, (unsigned int)lock_pid, - fsp->fsp_name, (int)lock_timeout )); - - if (locktype & LOCKING_ANDX_CANCEL_LOCK) { - struct blocking_lock_record *blr = NULL; - - if (lp_blocking_locks(SNUM(conn))) { - - /* Schedule a message to ourselves to - remove the blocking lock record and - return the right error. */ - - blr = blocking_lock_cancel(fsp, - lock_pid, - offset, - count, - WINDOWS_LOCK, - locktype, - NT_STATUS_FILE_LOCK_CONFLICT); - if (blr == NULL) { - END_PROFILE(SMBlockingX); - reply_nterror( - req, - NT_STATUS_DOS( - ERRDOS, - ERRcancelviolation)); - return; - } - } - /* Remove a matching pending lock. */ - status = do_lock_cancel(fsp, - lock_pid, - count, - offset, - WINDOWS_LOCK, - blr); - } else { - bool blocking_lock = lock_timeout ? True : False; - bool defer_lock = False; - struct byte_range_lock *br_lck; - uint32 block_smbpid; - - br_lck = do_lock(smbd_messaging_context(), - fsp, - lock_pid, - count, - offset, - lock_type, - WINDOWS_LOCK, - blocking_lock, - &status, - &block_smbpid, - NULL); - - if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) { - /* Windows internal resolution for blocking locks seems - to be about 200ms... Don't wait for less than that. JRA. */ - if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) { - lock_timeout = lp_lock_spin_time(); - } - defer_lock = True; - } - - /* This heuristic seems to match W2K3 very well. If a - lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT - it pretends we asked for a timeout of between 150 - 300 milliseconds as - far as I can tell. Replacement for do_lock_spin(). JRA. */ - - if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock && - NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) { - defer_lock = True; - lock_timeout = lp_lock_spin_time(); - } - - if (br_lck && defer_lock) { - /* - * A blocking lock was requested. Package up - * this smb into a queued request and push it - * onto the blocking lock queue. - */ - if(push_blocking_lock_request(br_lck, - req, - fsp, - lock_timeout, - i, - lock_pid, - lock_type, - WINDOWS_LOCK, - offset, - count, - block_smbpid)) { - TALLOC_FREE(br_lck); - END_PROFILE(SMBlockingX); - return; - } - } - - TALLOC_FREE(br_lck); - } - - if (NT_STATUS_V(status)) { - break; - } } - /* If any of the above locks failed, then we must unlock - all of the previous locks (X/Open spec). */ - if (num_locks != 0 && !NT_STATUS_IS_OK(status)) { - - if (locktype & LOCKING_ANDX_CANCEL_LOCK) { - i = -1; /* we want to skip the for loop */ - } - - /* - * Ensure we don't do a remove on the lock that just failed, - * as under POSIX rules, if we have a lock already there, we - * will delete it (and we shouldn't) ..... - */ - for(i--; i >= 0; i--) { - lock_pid = get_lock_pid( data, i, large_file_format); - count = get_lock_count( data, i, large_file_format); - offset = get_lock_offset( data, i, large_file_format, - &err); - - /* - * There is no error code marked "stupid client - * bug".... :-). - */ - if(err) { - END_PROFILE(SMBlockingX); - reply_doserror(req, ERRDOS, ERRnoaccess); - return; - } - - do_unlock(smbd_messaging_context(), - fsp, - lock_pid, - count, - offset, - WINDOWS_LOCK); - } + status = smbd_do_locking(req, fsp, + locktype, lock_timeout, + num_ulocks, ulocks, + num_locks, locks, + &async); + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBlockingX); reply_nterror(req, status); return; } + if (async) { + END_PROFILE(SMBlockingX); + return; + } reply_outbuf(req, 2, 0); -- cgit From 8d534d45a5d21967e2d9bca1ac34a55f1518fe42 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2009 18:09:16 +0200 Subject: s3:smbd: make smbd_do_locking() non static metze --- source3/smbd/globals.h | 17 +++++++++++++++++ source3/smbd/reply.c | 25 +++++++++---------------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 3d195c84f0..8163213dd0 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -168,6 +168,23 @@ NTSTATUS smb2_signing_check_pdu(DATA_BLOB session_key, const struct iovec *vector, int count); +struct smbd_lock_element { + uint32_t smbpid; + enum brl_type brltype; + uint64_t offset; + uint64_t count; +}; + +NTSTATUS smbd_do_locking(struct smb_request *req, + files_struct *fsp, + uint8_t type, + int32_t timeout, + uint16_t num_ulocks, + struct smbd_lock_element *ulocks, + uint16_t num_locks, + struct smbd_lock_element *locks, + bool *async); + void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn, const char *reason, const char *location); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 4a915d6f90..98ee83ea83 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -7223,22 +7223,15 @@ uint64_t get_lock_offset(const uint8_t *data, int data_offset, return offset; } -struct smbd_lock_element { - uint32_t smbpid; - enum brl_type brltype; - uint64_t offset; - uint64_t count; -}; - -static NTSTATUS smbd_do_locking(struct smb_request *req, - files_struct *fsp, - uint8_t type, - int32_t timeout, - uint16_t num_ulocks, - struct smbd_lock_element *ulocks, - uint16_t num_locks, - struct smbd_lock_element *locks, - bool *async) +NTSTATUS smbd_do_locking(struct smb_request *req, + files_struct *fsp, + uint8_t type, + int32_t timeout, + uint16_t num_ulocks, + struct smbd_lock_element *ulocks, + uint16_t num_locks, + struct smbd_lock_element *locks, + bool *async) { connection_struct *conn = req->conn; int i; -- cgit From 67c7b7f90bd1bad265e892bb00abf649b22345b6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2009 13:13:32 +0200 Subject: s3:smbd: add support for SMB2 Lock metze --- source3/smbd/smb2_lock.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 151 insertions(+), 1 deletion(-) diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 06e97b97b0..325c789320 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -190,6 +190,13 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, struct smb_request *smbreq; connection_struct *conn = smb2req->tcon->compat_conn; files_struct *fsp; + int32_t timeout = -1; + uint8_t type = 0; + bool isunlock = false; + uint16_t i; + struct smbd_lock_element *locks; + NTSTATUS status; + bool async = false; req = tevent_req_create(mem_ctx, &state, struct smbd_smb2_lock_state); @@ -220,7 +227,150 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + locks = talloc_array(state, struct smbd_lock_element, in_lock_count); + if (locks == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return tevent_req_post(req, ev); + } + + switch (in_locks[0].flags) { + case SMB2_LOCK_FLAG_SHARED: + case SMB2_LOCK_FLAG_EXCLUSIVE: + if (in_lock_count > 1) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + timeout = -1; + break; + + case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY: + case SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY: + timeout = 0; + break; + + case SMB2_LOCK_FLAG_UNLOCK: + /* only the first lock gives the UNLOCK bit - see + MS-SMB2 3.3.5.14 */ + isunlock = true; + timeout = 0; + break; + + default: + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + for (i=0; i 0) { + tevent_req_nterror(req, + NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + if (isunlock) { + tevent_req_nterror(req, + NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + break; + + case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY: + case SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY: + if (isunlock) { + tevent_req_nterror(req, + NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + break; + + case SMB2_LOCK_FLAG_UNLOCK: + if (!isunlock) { + tevent_req_nterror(req, + NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + break; + + default: + if (isunlock) { + /* + * is the first element was a UNLOCK + * we need to deferr the error response + * to the backend, because we need to process + * all unlock elements before + */ + invalid = true; + break; + } + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + locks[i].smbpid = in_smbpid; + locks[i].offset = in_locks[i].offset; + locks[i].count = in_locks[i].length; + + if (in_locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE) { + locks[i].brltype = WRITE_LOCK; + } else if (in_locks[i].flags & SMB2_LOCK_FLAG_SHARED) { + locks[i].brltype = READ_LOCK; + } else if (invalid) { + /* + * this is an invalid UNLOCK element + * and the backend needs to test for + * brltype != UNLOCK_LOCK and return + * NT_STATUS_INVALID_PARAMER + */ + locks[i].brltype = READ_LOCK; + } else { + locks[i].brltype = UNLOCK_LOCK; + } + + max_count = UINT64_MAX - locks[i].offset; + if (locks[i].count > max_count) { + tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_RANGE); + return tevent_req_post(req, ev); + } + } + + if (isunlock) { + status = smbd_do_locking(smbreq, fsp, + 0, + timeout, + in_lock_count, + locks, + 0, + NULL, + &async); + } else { + status = smbd_do_locking(smbreq, fsp, + 0, + timeout, + 0, + NULL, + in_lock_count, + locks, + &async); + } + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { + status = NT_STATUS_LOCK_NOT_GRANTED; + } + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + if (async) { + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return tevent_req_post(req, ev); + } + + tevent_req_done(req); return tevent_req_post(req, ev); } -- cgit From 0a0bff353e3cd8287166c7ed907a50a8599b0e03 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 17:29:22 +0200 Subject: Fix our base64 implementation for blobs of length 4.... The additional length check bit us exactly at 4, removing it. The torture test survives valgrind up to 2000 bytes :-) --- source3/lib/util_str.c | 2 +- source3/script/tests/test_smbtorture_s3.sh | 1 + source3/torture/torture.c | 34 ++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index cdd7d0a300..0aff9439e9 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1932,7 +1932,7 @@ char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data) result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */ SMB_ASSERT(result != NULL); - while (len-- && out_cnt < (data.length * 2) - 5) { + while (len--) { int c = (unsigned char) *(data.data++); bits += c; char_count++; diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh index c577ed18d4..4301081cec 100755 --- a/source3/script/tests/test_smbtorture_s3.sh +++ b/source3/script/tests/test_smbtorture_s3.sh @@ -29,6 +29,7 @@ tests="$tests DIR DIR1 TCON TCONDEV RW1 RW2 RW3" tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K" tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE CHAIN1" tests="$tests GETADDRINFO POSIX UID-REGRESSION-TEST SHORTNAME-TEST" +tests="$tests LOCAL-BASE64" skipped1="RANDOMIPC NEGNOWAIT NBENCH ERRMAPEXTRACT TRANS2SCAN NTTRANSSCAN" skipped2="DENY1 DENY2 OPENATTR CASETABLE EATEST" diff --git a/source3/torture/torture.c b/source3/torture/torture.c index aa7e83bcc8..15083ef90d 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -5749,6 +5749,39 @@ static bool run_local_substitute(int dummy) return ok; } +static bool run_local_base64(int dummy) +{ + int i; + bool ret = true; + + for (i=1; i<2000; i++) { + DATA_BLOB blob1, blob2; + char *b64; + + blob1.data = talloc_array(talloc_tos(), uint8_t, i); + blob1.length = i; + generate_random_buffer(blob1.data, blob1.length); + + b64 = base64_encode_data_blob(talloc_tos(), blob1); + if (b64 == NULL) { + d_fprintf(stderr, "base64_encode_data_blob failed " + "for %d bytes\n", i); + ret = false; + } + blob2 = base64_decode_data_blob(b64); + TALLOC_FREE(b64); + + if (data_blob_cmp(&blob1, &blob2)) { + d_fprintf(stderr, "data_blob_cmp failed for %d " + "bytes\n", i); + ret = false; + } + TALLOC_FREE(blob1.data); + data_blob_free(&blob2); + } + return ret; +} + static bool run_local_gencache(int dummy) { char *val; @@ -6487,6 +6520,7 @@ static struct { { "STREAMERROR", run_streamerror }, { "LOCAL-SUBSTITUTE", run_local_substitute, 0}, { "LOCAL-GENCACHE", run_local_gencache, 0}, + { "LOCAL-BASE64", run_local_base64, 0}, { "LOCAL-RBTREE", run_local_rbtree, 0}, { "LOCAL-MEMCACHE", run_local_memcache, 0}, { "LOCAL-STREAM-NAME", run_local_stream_name, 0}, -- cgit From 3969f65aaa1c0e5d3158f089a2fe496af6dd60b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 17:36:18 +0200 Subject: Fix&Run local-gencache --- source3/script/tests/test_smbtorture_s3.sh | 2 +- source3/torture/torture.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh index 4301081cec..2894d7e90a 100755 --- a/source3/script/tests/test_smbtorture_s3.sh +++ b/source3/script/tests/test_smbtorture_s3.sh @@ -29,7 +29,7 @@ tests="$tests DIR DIR1 TCON TCONDEV RW1 RW2 RW3" tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K" tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE CHAIN1" tests="$tests GETADDRINFO POSIX UID-REGRESSION-TEST SHORTNAME-TEST" -tests="$tests LOCAL-BASE64" +tests="$tests LOCAL-BASE64 LOCAL-GENCACHE" skipped1="RANDOMIPC NEGNOWAIT NBENCH ERRMAPEXTRACT TRANS2SCAN NTTRANSSCAN" skipped2="DENY1 DENY2 OPENATTR CASETABLE EATEST" diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 15083ef90d..8e38093e33 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -5829,15 +5829,13 @@ static bool run_local_gencache(int dummy) } blob = data_blob_string_const_null("bar"); - tm = time(NULL); + tm = time(NULL) + 60; if (!gencache_set_data_blob("foo", &blob, tm)) { d_printf("%s: gencache_set_data_blob() failed\n", __location__); return False; } - data_blob_free(&blob); - if (!gencache_get_data_blob("foo", &blob, NULL)) { d_printf("%s: gencache_get_data_blob() failed\n", __location__); return False; -- cgit From 4e516fb19146399546bd9cd249ee3adb60c07e16 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 12:03:51 -0700 Subject: s3 smb2: Remove unused variable --- source3/smbd/smb2_lock.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 325c789320..121b4eb24d 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -191,7 +191,6 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, connection_struct *conn = smb2req->tcon->compat_conn; files_struct *fsp; int32_t timeout = -1; - uint8_t type = 0; bool isunlock = false; uint16_t i; struct smbd_lock_element *locks; -- cgit From d8556bbf1394439d0880983c7dff67dd8dda66b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 5 Jul 2009 14:39:16 +0200 Subject: Quieten events and tldap debug messages --- source3/lib/events.c | 2 +- source3/passdb/pdb_ads.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/lib/events.c b/source3/lib/events.c index 08debb4252..7a06ad0829 100644 --- a/source3/lib/events.c +++ b/source3/lib/events.c @@ -286,7 +286,7 @@ static void s3_event_debug(void *context, enum tevent_debug_level level, samba_level = 2; break; case TEVENT_DEBUG_TRACE: - samba_level = 10; + samba_level = 11; break; }; diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index eec63728ca..82bc1677f0 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -2111,7 +2111,7 @@ static void s3_tldap_debug(void *context, enum tldap_debug_level level, samba_level = 2; break; case TLDAP_DEBUG_TRACE: - samba_level = 10; + samba_level = 11; break; }; -- cgit From afc6f607d5c8ba995b55464525edc8bf8f7a040c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 9 Jul 2009 15:58:10 +0200 Subject: Return 0 domains from enum_trusteddoms --- source3/passdb/pdb_ads.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index 82bc1677f0..ddfeb8ed80 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -2022,7 +2022,9 @@ static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m, uint32 *num_domains, struct trustdom_info ***domains) { - return NT_STATUS_NOT_IMPLEMENTED; + *num_domains = 0; + *domains = NULL; + return NT_STATUS_OK; } static void pdb_ads_init_methods(struct pdb_methods *m) -- cgit From 361aa19e69d4176dd8c30f485cc637cd33308d62 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Jul 2009 15:50:40 -0700 Subject: Add hash values to the xattr ACLS to determine when an underlying POSIX ACL is changed out from under us. Passes RAW-ACL test up to "invalid owner" problem when trying to create a file owned by Everyone. Now needs porting to modules/vfs_acl_tdb.c Jeremy. --- source3/modules/vfs_acl_xattr.c | 213 +++++++++++++++++++++++++++++----------- 1 file changed, 158 insertions(+), 55 deletions(-) diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index 66bf21c4f7..eb6653bcd1 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -27,13 +27,45 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS +static NTSTATUS create_acl_blob(const struct security_descriptor *psd, + DATA_BLOB *pblob, + uint8_t hash[16]); + +#define HASH_SECURITY_INFO (OWNER_SECURITY_INFORMATION | \ + GROUP_SECURITY_INFORMATION | \ + DACL_SECURITY_INFORMATION | \ + SACL_SECURITY_INFORMATION) + +/******************************************************************* + Hash a security descriptor. +*******************************************************************/ + +static NTSTATUS hash_sd(struct security_descriptor *psd, + uint8_t hash[16]) +{ + DATA_BLOB blob; + struct MD5Context tctx; + NTSTATUS status; + + memset(hash, '\0', 16); + status = create_acl_blob(psd, &blob, hash); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + MD5Init(&tctx); + MD5Update(&tctx, blob.data, blob.length); + MD5Final(hash, &tctx); + return NT_STATUS_OK; +} + /******************************************************************* Parse out a struct security_descriptor from a DATA_BLOB. *******************************************************************/ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, uint32 security_info, - struct security_descriptor **ppdesc) + struct security_descriptor **ppdesc, + uint8_t hash[16]) { TALLOC_CTX *ctx = talloc_tos(); struct xattr_NTACL xacl; @@ -64,6 +96,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, ? xacl.info.sd_hs->sd->dacl : NULL, &sd_size); + memcpy(hash, xacl.info.sd_hs->hash, 16); TALLOC_FREE(xacl.info.sd); return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; @@ -131,7 +164,9 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, Create a DATA_BLOB from a security descriptor. *******************************************************************/ -static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob) +static NTSTATUS create_acl_blob(const struct security_descriptor *psd, + DATA_BLOB *pblob, + uint8_t hash[16]) { struct xattr_NTACL xacl; struct security_descriptor_hash sd_hs; @@ -144,7 +179,7 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB xacl.version = 2; xacl.info.sd_hs = &sd_hs; xacl.info.sd_hs->sd = CONST_DISCARD(struct security_descriptor *, psd); - memset(&xacl.info.sd_hs->hash[0], '\0', 16); + memcpy(&xacl.info.sd_hs->hash[0], hash, 16); ndr_err = ndr_push_struct_blob( pblob, ctx, NULL, &xacl, @@ -242,9 +277,11 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, uint32 security_info, struct security_descriptor **ppdesc) { - TALLOC_CTX *ctx = talloc_tos(); DATA_BLOB blob; NTSTATUS status; + uint8_t hash[16]; + uint8_t hash_tmp[16]; + struct security_descriptor *pdesc_next = NULL; if (fsp && name == NULL) { name = fsp->fsp_name; @@ -252,19 +289,74 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, DEBUG(10, ("get_nt_acl_xattr_internal: name=%s\n", name)); - status = get_acl_blob(ctx, handle, fsp, name, &blob); + status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status))); return status; } - status = parse_acl_blob(&blob, security_info, ppdesc); + status = parse_acl_blob(&blob, security_info, ppdesc, &hash[0]); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("parse_acl_blob returned %s\n", nt_errstr(status))); return status; } + /* If there was no stored hash, don't check. */ + memset(&hash_tmp[0], '\0', 16); + if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) { + /* No hash, goto return blob sd. */ + goto out; + } + + /* Get the full underlying sd, then hash. */ + if (fsp) { + status = SMB_VFS_NEXT_FGET_NT_ACL(handle, + fsp, + HASH_SECURITY_INFO, + &pdesc_next); + } else { + status = SMB_VFS_NEXT_GET_NT_ACL(handle, + name, + HASH_SECURITY_INFO, + &pdesc_next); + } + + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + status = hash_sd(pdesc_next, hash_tmp); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) { + TALLOC_FREE(pdesc_next); + /* Hash matches, return blob sd. */ + goto out; + } + + /* Hash doesn't match, return underlying sd. */ + + if (!(security_info & OWNER_SECURITY_INFORMATION)) { + pdesc_next->owner_sid = NULL; + } + if (!(security_info & GROUP_SECURITY_INFORMATION)) { + pdesc_next->group_sid = NULL; + } + if (!(security_info & DACL_SECURITY_INFORMATION)) { + pdesc_next->dacl = NULL; + } + if (!(security_info & SACL_SECURITY_INFORMATION)) { + pdesc_next->sacl = NULL; + } + + TALLOC_FREE(*ppdesc); + *ppdesc = pdesc_next; + + out: + TALLOC_FREE(blob.data); return status; } @@ -324,9 +416,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, NTSTATUS status; struct security_descriptor *parent_desc = NULL; struct security_descriptor *psd = NULL; + struct security_descriptor *pdesc_next = NULL; DATA_BLOB blob; size_t size; char *parent_name; + uint8_t hash[16]; if (!parent_dirname(ctx, fname, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; @@ -382,11 +476,9 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { if (fsp && fsp->posix_open) { - ret = vfs_lstat_smb_fname(handle->conn, fname, - &sbuf); + ret = vfs_lstat_smb_fname(handle->conn,fname, &sbuf); } else { - ret = vfs_stat_smb_fname(handle->conn, fname, - &sbuf); + ret = vfs_stat_smb_fname(handle->conn,fname, &sbuf); } } if (ret == -1) { @@ -403,7 +495,28 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, } } - status = create_acl_blob(psd, &blob); + /* Object exists. Read the current SD to get the hash. */ + if (fsp) { + status = SMB_VFS_NEXT_FGET_NT_ACL(handle, + fsp, + HASH_SECURITY_INFO, + &pdesc_next); + } else { + status = SMB_VFS_NEXT_GET_NT_ACL(handle, + fname, + HASH_SECURITY_INFO, + &pdesc_next); + } + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = hash_sd(pdesc_next, hash); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = create_acl_blob(psd, &blob, hash); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -430,6 +543,13 @@ static int open_acl_xattr(vfs_handle_struct *handle, char *fname = NULL; NTSTATUS status; + if (fsp->base_fsp) { + /* Stream open. Base filename open already did the ACL check. */ + DEBUG(10,("open_acl_xattr: stream open on %s\n", + smb_fname_str_dbg(smb_fname) )); + return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); + } + status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); if (!NT_STATUS_IS_OK(status)) { @@ -497,23 +617,8 @@ static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t m static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, struct security_descriptor **ppdesc) { - NTSTATUS status = get_nt_acl_xattr_internal(handle, fsp, + return get_nt_acl_xattr_internal(handle, fsp, NULL, security_info, ppdesc); - if (NT_STATUS_IS_OK(status)) { - if (DEBUGLEVEL >= 10) { - DEBUG(10,("fget_nt_acl_xattr: returning xattr sd for file %s\n", - fsp->fsp_name)); - NDR_PRINT_DEBUG(security_descriptor, *ppdesc); - } - return NT_STATUS_OK; - } - - DEBUG(10,("fget_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n", - fsp->fsp_name, - nt_errstr(status) )); - - return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, - security_info, ppdesc); } /********************************************************************* @@ -523,23 +628,8 @@ static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle, const char *name, uint32 security_info, struct security_descriptor **ppdesc) { - NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL, + return get_nt_acl_xattr_internal(handle, NULL, name, security_info, ppdesc); - if (NT_STATUS_IS_OK(status)) { - if (DEBUGLEVEL >= 10) { - DEBUG(10,("get_nt_acl_xattr: returning xattr sd for file %s\n", - name)); - NDR_PRINT_DEBUG(security_descriptor, *ppdesc); - } - return NT_STATUS_OK; - } - - DEBUG(10,("get_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n", - name, - nt_errstr(status) )); - - return SMB_VFS_NEXT_GET_NT_ACL(handle, name, - security_info, ppdesc); } /********************************************************************* @@ -551,6 +641,8 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, { NTSTATUS status; DATA_BLOB blob; + struct security_descriptor *pdesc_next = NULL; + uint8_t hash[16]; if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", @@ -559,11 +651,6 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, CONST_DISCARD(struct security_descriptor *,psd)); } - status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - /* Ensure owner and group are set. */ if (!psd->owner_sid || !psd->group_sid) { int ret; @@ -576,13 +663,9 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, } if (fsp->is_directory || fsp->fh->fd == -1) { if (fsp->posix_open) { - ret = vfs_lstat_smb_fname(fsp->conn, - fsp->fsp_name, - &sbuf); + ret = vfs_lstat_smb_fname(fsp->conn,fsp->fsp_name, &sbuf); } else { - ret = vfs_stat_smb_fname(fsp->conn, - fsp->fsp_name, - &sbuf); + ret = vfs_stat_smb_fname(fsp->conn,fsp->fsp_name, &sbuf); } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); @@ -600,6 +683,26 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, psd = nc_psd; } + status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* Get the full underlying sd, then hash. */ + status = SMB_VFS_NEXT_FGET_NT_ACL(handle, + fsp, + HASH_SECURITY_INFO, + &pdesc_next); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = hash_sd(pdesc_next, hash); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + #if 0 if ((security_info_sent & DACL_SECURITY_INFORMATION) && psd->dacl != NULL && @@ -624,7 +727,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } - create_acl_blob(psd, &blob); + create_acl_blob(psd, &blob, hash); store_acl_blob_fsp(handle, fsp, &blob); return NT_STATUS_OK; -- cgit From 2000421c592b672898f85758638be74d8485da1e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Jul 2009 18:23:00 -0700 Subject: Remove reply_unixerror() - no longer needed. Should make Metze's refactoring a lot easier. Jeremy. --- source3/include/proto.h | 2 -- source3/include/smb_macros.h | 1 - source3/smbd/error.c | 30 ------------------ source3/smbd/fileio.c | 1 + source3/smbd/pipes.c | 23 +++++++++++--- source3/smbd/reply.c | 72 ++++++++++++++++++++++++++------------------ source3/smbd/trans2.c | 37 +++++++++++------------ 7 files changed, 79 insertions(+), 87 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index c0f4dc10d8..27b5f45eb0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6260,8 +6260,6 @@ void reply_dos_error(struct smb_request *req, uint8 eclass, uint32 ecode, void reply_both_error(struct smb_request *req, uint8 eclass, uint32 ecode, NTSTATUS status, int line, const char *file); void reply_openerror(struct smb_request *req, NTSTATUS status); -void reply_unix_error(struct smb_request *req, uint8 defclass, uint32 defcode, - NTSTATUS defstatus, int line, const char *file); /* The following definitions come from smbd/fake_file.c */ diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index 7528883c2d..10ee78b394 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -115,7 +115,6 @@ #define reply_force_nterror(req,status) reply_force_nt_error(req,status,__LINE__,__FILE__) #define reply_doserror(req,eclass,ecode) reply_dos_error(req,eclass,ecode,__LINE__,__FILE__) #define reply_botherror(req,status,eclass,ecode) reply_both_error(req,eclass,ecode,status,__LINE__,__FILE__) -#define reply_unixerror(req,defclass,deferror) reply_unix_error(req,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__) #if 0 /* defined in IDL */ diff --git a/source3/smbd/error.c b/source3/smbd/error.c index ce22f86414..874efa2a0b 100644 --- a/source3/smbd/error.c +++ b/source3/smbd/error.c @@ -136,33 +136,3 @@ void reply_openerror(struct smb_request *req, NTSTATUS status) reply_nterror(req, status); } } - -void reply_unix_error(struct smb_request *req, uint8 defclass, uint32 defcode, - NTSTATUS defstatus, int line, const char *file) -{ - int eclass=defclass; - int ecode=defcode; - NTSTATUS ntstatus = defstatus; - int i=0; - - TALLOC_FREE(req->outbuf); - reply_outbuf(req, 0, 0); - - if (errno != 0) { - DEBUG(3,("unix_error_packet: error string = %s\n", - strerror(errno))); - - while (unix_dos_nt_errmap[i].dos_class != 0) { - if (unix_dos_nt_errmap[i].unix_error == errno) { - eclass = unix_dos_nt_errmap[i].dos_class; - ecode = unix_dos_nt_errmap[i].dos_code; - ntstatus = unix_dos_nt_errmap[i].nt_error; - break; - } - i++; - } - } - - error_packet_set((char *)req->outbuf, eclass, ecode, ntstatus, - line, file); -} diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 0c13b845df..60cef09b3b 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -57,6 +57,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) /* you can't read from print files */ if (fsp->print_file) { + errno = EBADF; return -1; } diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 7ae7435646..799568d0d5 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -203,8 +203,14 @@ static void pipe_write_done(struct tevent_req *subreq) status = np_write_recv(subreq, &nwritten); TALLOC_FREE(subreq); - if ((nwritten == 0 && state->numtowrite != 0) || (nwritten < 0)) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + if (nwritten < 0) { + reply_nterror(req, status); + goto send; + } + + /* Looks bogus to me now. Needs to be removed ? JRA. */ + if ((nwritten == 0 && state->numtowrite != 0)) { + reply_doserror(req, ERRDOS, ERRnoaccess); goto send; } @@ -283,7 +289,7 @@ void reply_pipe_write_and_X(struct smb_request *req) DEBUG(0,("reply_pipe_write_and_X: start of message " "set and not enough data sent.(%u)\n", (unsigned int)state->numtowrite )); - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -313,8 +319,15 @@ static void pipe_write_andx_done(struct tevent_req *subreq) status = np_write_recv(subreq, &nwritten); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status) || (nwritten != state->numtowrite)) { - reply_unixerror(req, ERRDOS,ERRnoaccess); + + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + goto done; + } + + /* Looks bogus to me now. Is this error message correct ? JRA. */ + if (nwritten != state->numtowrite) { + reply_doserror(req, ERRDOS,ERRnoaccess); goto done; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 98ee83ea83..e35c5bc6d6 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1106,7 +1106,7 @@ void reply_getatr(struct smb_request *req) DEBUG(3,("reply_getatr: stat of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req, ERRDOS,ERRbadfile); + reply_nterror(req, map_nt_error_from_unix(errno)); goto out; } @@ -1220,7 +1220,7 @@ void reply_setatr(struct smb_request *req) ft.mtime = convert_time_t_to_timespec(mtime); status = smb_set_file_time(conn, NULL, smb_fname, &ft, true); if (!NT_STATUS_IS_OK(status)) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, status); goto out; } @@ -1232,7 +1232,7 @@ void reply_setatr(struct smb_request *req) if (file_set_dosmode(conn, smb_fname, mode, NULL, false) != 0) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); goto out; } } @@ -1258,7 +1258,7 @@ void reply_dskattr(struct smb_request *req) START_PROFILE(SMBdskattr); if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_unixerror(req, ERRHRD, ERRgeneral); + reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBdskattr); return; } @@ -2271,7 +2271,7 @@ void reply_ctemp(struct smb_request *req) tmpfd = mkstemp(smb_fname->base_name); if (tmpfd == -1) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); goto out; } @@ -3269,7 +3269,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", nread = read_file(fsp,data,startpos,numtoread); if (nread < 0) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBlockread); return; } @@ -3363,7 +3363,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", nread = read_file(fsp,data,startpos,numtoread); if (nread < 0) { - reply_unixerror(req, ERRDOS,ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); goto strict_unlock; } @@ -3425,9 +3425,10 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, SMB_STRUCT_STAT sbuf; ssize_t nread = -1; struct lock_struct lock; + int saved_errno = 0; if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } @@ -3565,11 +3566,12 @@ nosendfile_read: reply_outbuf(req, 12, smb_maxcnt); nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt); + saved_errno = errno; SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); if (nread < 0) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(saved_errno)); return; } @@ -3810,7 +3812,7 @@ void reply_writebraw(struct smb_request *req) (int)nwritten, (int)write_through)); if (nwritten < (ssize_t)numtowrite) { - reply_unixerror(req, ERRHRD, ERRdiskfull); + reply_doserror(req, ERRHRD, ERRdiskfull); error_to_writebrawerr(req); goto strict_unlock; } @@ -3879,7 +3881,7 @@ void reply_writebraw(struct smb_request *req) nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite); if (nwritten == -1) { TALLOC_FREE(buf); - reply_unixerror(req, ERRHRD, ERRdiskfull); + reply_nterror(req, map_nt_error_from_unix(errno)); error_to_writebrawerr(req); goto strict_unlock; } @@ -3958,6 +3960,7 @@ void reply_writeunlock(struct smb_request *req) NTSTATUS status = NT_STATUS_OK; files_struct *fsp; struct lock_struct lock; + int saved_errno = 0; START_PROFILE(SMBwriteunlock); @@ -4003,6 +4006,7 @@ void reply_writeunlock(struct smb_request *req) nwritten = 0; } else { nwritten = write_file(req,fsp,data,startpos,numtowrite); + saved_errno = errno; } status = sync_file(conn, fsp, False /* write through */); @@ -4013,8 +4017,13 @@ void reply_writeunlock(struct smb_request *req) goto strict_unlock; } - if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) { - reply_unixerror(req, ERRHRD, ERRdiskfull); + if(nwritten < 0) { + reply_nterror(req, map_nt_error_from_unix(saved_errno)); + goto strict_unlock; + } + + if((nwritten < numtowrite) && (numtowrite != 0)) { + reply_doserror(req, ERRHRD, ERRdiskfull); goto strict_unlock; } @@ -4065,6 +4074,7 @@ void reply_write(struct smb_request *req) files_struct *fsp; struct lock_struct lock; NTSTATUS status; + int saved_errno = 0; START_PROFILE(SMBwrite); @@ -4141,8 +4151,13 @@ void reply_write(struct smb_request *req) goto strict_unlock; } - if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { - reply_unixerror(req, ERRHRD, ERRdiskfull); + if(nwritten < 0) { + reply_nterror(req, map_nt_error_from_unix(saved_errno)); + goto strict_unlock; + } + + if((nwritten == 0) && (numtowrite != 0)) { + reply_doserror(req, ERRHRD, ERRdiskfull); goto strict_unlock; } @@ -4389,8 +4404,13 @@ void reply_write_and_X(struct smb_request *req) nwritten = write_file(req,fsp,data,startpos,numtowrite); } - if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { - reply_unixerror(req, ERRHRD, ERRdiskfull); + if(nwritten < 0) { + reply_nterror(req, map_nt_error_from_unix(errno)); + goto strict_unlock; + } + + if((nwritten == 0) && (numtowrite != 0)) { + reply_doserror(req, ERRHRD, ERRdiskfull); goto strict_unlock; } @@ -4484,8 +4504,8 @@ void reply_lseek(struct smb_request *req) SMB_STRUCT_STAT sbuf; if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - reply_unixerror(req, ERRDOS, - ERRnoaccess); + reply_nterror(req, + map_nt_error_from_unix(errno)); END_PROFILE(SMBlseek); return; } @@ -4497,7 +4517,7 @@ void reply_lseek(struct smb_request *req) } if(res == -1) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBlseek); return; } @@ -5197,7 +5217,7 @@ void reply_printwrite(struct smb_request *req) data = (const char *)req->buf + 3; if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) { - reply_unixerror(req, ERRHRD, ERRdiskfull); + reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBsplwr); return; } @@ -6756,7 +6776,6 @@ void reply_copy(struct smb_request *req) const char *p; int count=0; int error = ERRnoaccess; - int err = 0; int tid2; int ofun; int flags; @@ -7059,13 +7078,6 @@ void reply_copy(struct smb_request *req) } if (count == 0) { - if(err) { - /* Error on close... */ - errno = err; - reply_unixerror(req, ERRHRD, ERRgeneral); - goto out; - } - reply_doserror(req, ERRDOS, error); goto out; } @@ -7833,7 +7845,7 @@ void reply_getattrE(struct smb_request *req) /* Do an fstat on this file */ if(fsp_stat(fsp, &sbuf)) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBgetattrE); return; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 4bf27863bd..6a18f0f710 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2697,7 +2697,7 @@ static void call_trans2qfsinfo(connection_struct *conn, uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 18; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_unixerror(req, ERRHRD, ERRgeneral); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } @@ -2818,7 +2818,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 24; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_unixerror(req, ERRHRD, ERRgeneral); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } block_size = lp_block_size(snum); @@ -2851,7 +2851,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 32; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_unixerror(req, ERRHRD, ERRgeneral); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } block_size = lp_block_size(snum); @@ -3992,7 +3992,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "(%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req,ERRDOS,ERRbadpath); + reply_nterror(req,map_nt_error_from_unix(errno)); return; } } else if (SMB_VFS_STAT(conn, smb_fname)) { @@ -4000,7 +4000,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "SMB_VFS_STAT of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadpath); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } @@ -4017,7 +4017,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { DEBUG(3, ("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadfid); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } pos = fsp->fh->position_information; @@ -4090,8 +4090,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "(%s)\n", smb_fname_str_dbg(smb_fname_base), strerror(errno))); + reply_nterror(req,map_nt_error_from_unix(errno)); TALLOC_FREE(smb_fname_base); - reply_unixerror(req,ERRDOS,ERRbadpath); return; } } else { @@ -4101,8 +4101,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "(%s)\n", smb_fname_str_dbg(smb_fname_base), strerror(errno))); + reply_nterror(req,map_nt_error_from_unix(errno)); TALLOC_FREE(smb_fname_base); - reply_unixerror(req,ERRDOS,ERRbadpath); return; } } @@ -4124,7 +4124,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "SMB_VFS_LSTAT of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadpath); + reply_nterror(req,map_nt_error_from_unix(errno)); return; } @@ -4139,7 +4139,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "SMB_VFS_STAT of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadpath); + reply_nterror(req,map_nt_error_from_unix(errno)); return; } } @@ -4700,19 +4700,18 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n")); #ifdef S_ISLNK if(!S_ISLNK(sbuf.st_ex_mode)) { - reply_unixerror(req, ERRSRV, + reply_doserror(req, ERRSRV, ERRbadlink); return; } #else - reply_unixerror(req, ERRDOS, ERRbadlink); + reply_doserror(req, ERRDOS, ERRbadlink); return; #endif len = SMB_VFS_READLINK(conn,fullpathname, buffer, PATH_MAX); if (len == -1) { - reply_unixerror(req, ERRDOS, - ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } buffer[len] = 0; @@ -6934,7 +6933,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, "(%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req,ERRDOS,ERRbadpath); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } } else { @@ -6943,7 +6942,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, "fileinfo of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req,ERRDOS,ERRbadpath); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } } @@ -6962,7 +6961,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, max_data_bytes); return; } else { - reply_unixerror(req, ERRDOS, ERRbadpath); + reply_doserror(req, ERRDOS, ERRbadpath); return; } } else { @@ -6977,7 +6976,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, DEBUG(3,("call_trans2setfilepathinfo: fstat " "of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadfid); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } } @@ -7027,7 +7026,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, "%s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadpath); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } } -- cgit From 20bc933c5b2f420f3588adf811a66aa886a1b41e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2009 18:51:59 +0200 Subject: s3:smbd: add missing return after reply_nterror() metze --- source3/smbd/trans2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 6a18f0f710..b7591c4bbb 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4455,6 +4455,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd reply_nterror( req, NT_STATUS_NO_MEMORY); + return; } len = srvstr_push(dstart, req->flags2, pdata+4, mangled_name, -- cgit From 8422e032339f624e6322a4a6a4938b1d84b347a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2009 19:04:58 +0200 Subject: s3:smbd: split out smbd_do_qfilepathinfo() from call_trans2qfilepathinfo() This prepares SMB2 GetInfo. metze --- source3/smbd/trans2.c | 1751 +++++++++++++++++++++++++------------------------ 1 file changed, 898 insertions(+), 853 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index b7591c4bbb..c9e7e4bbfb 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3878,951 +3878,1014 @@ static void call_trans2qpipeinfo(connection_struct *conn, return; } -/**************************************************************************** - Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by - file name or file id). -****************************************************************************/ - -static void call_trans2qfilepathinfo(connection_struct *conn, - struct smb_request *req, - unsigned int tran_call, - char **pparams, int total_params, - char **ppdata, int total_data, - unsigned int max_data_bytes) +static NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + const struct smb_filename *smb_fname, + bool delete_pending, + struct timespec write_time_ts, + bool ms_dfs_link, + struct ea_list *ea_list, + int lock_data_count, + char *lock_data, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + unsigned int *pdata_size) { - char *params = *pparams; char *pdata = *ppdata; char *dstart, *dend; - uint16 info_level; - int mode=0; - int nlink; - SMB_OFF_T file_size=0; - uint64_t allocation_size=0; - unsigned int data_size = 0; - unsigned int param_size = 2; + unsigned int data_size; + struct timespec create_time_ts, mtime_ts, atime_ts; + time_t create_time, mtime, atime; SMB_STRUCT_STAT sbuf; - char *dos_fname = NULL; - char *fname = NULL; - struct smb_filename *smb_fname = NULL; - char *fullpathname; - char *base_name; char *p; - SMB_OFF_T pos = 0; - bool delete_pending = False; - int len; - time_t create_time, mtime, atime; - struct timespec create_time_ts, mtime_ts, atime_ts; - struct timespec write_time_ts; - files_struct *fsp = NULL; - struct file_id fileid; - struct ea_list *ea_list = NULL; - char *lock_data = NULL; - bool ms_dfs_link = false; - TALLOC_CTX *ctx = talloc_tos(); - NTSTATUS status = NT_STATUS_OK; + char *fname; + char *base_name; + char *dos_fname; + int mode; + int nlink; + NTSTATUS status; + uint64_t file_size = 0; + uint64_t pos = 0; + uint64_t allocation_size = 0; - if (!params) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + sbuf = smb_fname->st; + + if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { + return NT_STATUS_INVALID_LEVEL; } - ZERO_STRUCT(write_time_ts); + status = get_full_smb_filename(mem_ctx, smb_fname, &fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - if (tran_call == TRANSACT2_QFILEINFO) { - if (total_params < 4) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } + DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n", + fname, fsp ? fsp->fnum : -1, info_level, max_data_bytes)); - if (IS_IPC(conn)) { - call_trans2qpipeinfo(conn, req, tran_call, - pparams, total_params, - ppdata, total_data, - max_data_bytes); - return; - } + if (ms_dfs_link) { + mode = dos_mode_msdfs(conn, smb_fname); + } else { + mode = dos_mode(conn, smb_fname); + } + if (!mode) + mode = FILE_ATTRIBUTE_NORMAL; - fsp = file_fsp(req, SVAL(params,0)); - info_level = SVAL(params,2); + nlink = sbuf.st_ex_nlink; - DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); + if (nlink && (mode&aDIR)) { + nlink = 1; + } - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; - } + if ((nlink > 0) && delete_pending) { + nlink -= 1; + } - /* Initial check for valid fsp ptr. */ - if (!check_fsp_open(conn, req, fsp)) { - return; - } + data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN; + *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); + if (*ppdata == NULL) { + return NT_STATUS_NO_MEMORY; + } + pdata = *ppdata; + dstart = pdata; + dend = dstart + data_size - 1; - fname = talloc_strdup(talloc_tos(),fsp->fsp_name); - if (!fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) { + update_stat_ex_mtime(&sbuf, write_time_ts); + } + + create_time_ts = sbuf.st_ex_btime; + mtime_ts = sbuf.st_ex_mtime; + atime_ts = sbuf.st_ex_atime; + + if (lp_dos_filetime_resolution(SNUM(conn))) { + dos_filetime_timespec(&create_time_ts); + dos_filetime_timespec(&mtime_ts); + dos_filetime_timespec(&atime_ts); + } + + create_time = convert_timespec_to_time_t(create_time_ts); + mtime = convert_timespec_to_time_t(mtime_ts); + atime = convert_timespec_to_time_t(atime_ts); + + p = strrchr_m(smb_fname->base_name,'/'); + if (!p) + base_name = smb_fname->base_name; + else + base_name = p+1; + + /* NT expects the name to be in an exact form of the *full* + filename. See the trans2 torture test */ + if (ISDOT(base_name)) { + dos_fname = talloc_strdup(mem_ctx, "\\"); + if (!dos_fname) { + return NT_STATUS_NO_MEMORY; + } + } else { + dos_fname = talloc_asprintf(mem_ctx, + "\\%s", + fname); + if (!dos_fname) { + return NT_STATUS_NO_MEMORY; } + string_replace(dos_fname, '/', '\\'); + } - status = create_synthetic_smb_fname_split(talloc_tos(), fname, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; + allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &sbuf); + + if (!fsp) { + /* Do we have this path open ? */ + files_struct *fsp1; + struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf); + fsp1 = file_find_di_first(fileid); + if (fsp1 && fsp1->initial_allocation_size) { + allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf); } + } - if(fsp->fake_file_handle) { - /* - * This is actually for the QUOTA_FAKE_FILE --metze - */ + if (!(mode & aDIR)) { + file_size = get_file_size_stat(&sbuf); + } - /* We know this name is ok, it's already passed the checks. */ + if (fsp && fsp->fh) { + pos = fsp->fh->position_information; + } - } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) { - /* - * This is actually a QFILEINFO on a directory - * handle (returned from an NT SMB). NT5.0 seems - * to do this call. JRA. - */ + switch (info_level) { + case SMB_INFO_STANDARD: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n")); + data_size = 22; + srv_put_dos_date2(pdata,l1_fdateCreation,create_time); + srv_put_dos_date2(pdata,l1_fdateLastAccess,atime); + srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */ + SIVAL(pdata,l1_cbFile,(uint32)file_size); + SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size); + SSVAL(pdata,l1_attrFile,mode); + break; - if (INFO_LEVEL_IS_UNIX(info_level)) { - /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { - DEBUG(3,("call_trans2qfilepathinfo: " - "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req,map_nt_error_from_unix(errno)); - return; - } - } else if (SMB_VFS_STAT(conn, smb_fname)) { - DEBUG(3,("call_trans2qfilepathinfo: " - "SMB_VFS_STAT of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } + case SMB_INFO_QUERY_EA_SIZE: + { + unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n")); + data_size = 26; + srv_put_dos_date2(pdata,0,create_time); + srv_put_dos_date2(pdata,4,atime); + srv_put_dos_date2(pdata,8,mtime); /* write time */ + SIVAL(pdata,12,(uint32)file_size); + SIVAL(pdata,16,(uint32)allocation_size); + SSVAL(pdata,20,mode); + SIVAL(pdata,22,ea_size); + break; + } - fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); - get_file_infos(fileid, &delete_pending, &write_time_ts); - } else { - /* - * Original code - this is an open file. - */ - if (!check_fsp(conn, req, fsp)) { - return; + case SMB_INFO_IS_NAME_VALID: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n")); + if (fsp) { + /* os/2 needs this ? really ?*/ + return NT_STATUS_DOS(ERRDOS, ERRbadfunc); } + /* This is only reached for qpathinfo */ + data_size = 0; + break; - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { - DEBUG(3, ("fstat of fnum %d failed (%s)\n", - fsp->fnum, strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; + case SMB_INFO_QUERY_EAS_FROM_LIST: + { + size_t total_ea_len = 0; + struct ea_list *ea_file_list = NULL; + + DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n")); + + ea_file_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); + ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len); + + if (!ea_list || (total_ea_len > data_size)) { + data_size = 4; + SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ + break; } - pos = fsp->fh->position_information; - fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); - get_file_infos(fileid, &delete_pending, &write_time_ts); - } - } else { - /* qpathinfo */ - if (total_params < 7) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list); + break; } - info_level = SVAL(params,0); + case SMB_INFO_QUERY_ALL_EAS: + { + /* We have data_size bytes to put EA's into. */ + size_t total_ea_len = 0; - DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level)); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n")); - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); + if (!ea_list || (total_ea_len > data_size)) { + data_size = 4; + SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ + break; + } + + data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list); + break; } - srvstr_get_path(ctx, params, req->flags2, &fname, ¶ms[6], - total_params - 6, - STR_TERMINATE, &status); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; - } + case SMB_FILE_BASIC_INFORMATION: + case SMB_QUERY_FILE_BASIC_INFO: - status = filename_convert(ctx, - conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - fname, - &smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, - NT_STATUS_PATH_NOT_COVERED, - ERRSRV, ERRbadpath); - return; + if (info_level == SMB_QUERY_FILE_BASIC_INFO) { + DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n")); + data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */ + } else { + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n")); + data_size = 40; + SIVAL(pdata,36,0); } - reply_nterror(req, status); - return; - } + put_long_date_timespec(pdata,create_time_ts); + put_long_date_timespec(pdata+8,atime_ts); + put_long_date_timespec(pdata+16,mtime_ts); /* write time */ + put_long_date_timespec(pdata+24,mtime_ts); /* change time */ + SIVAL(pdata,32,mode); - /* If this is a stream, check if there is a delete_pending. */ - if ((conn->fs_capabilities & FILE_NAMED_STREAMS) - && is_ntfs_stream_smb_fname(smb_fname)) { - struct smb_filename *smb_fname_base = NULL; + DEBUG(5,("SMB_QFBI - ")); + DEBUG(5,("create: %s ", ctime(&create_time))); + DEBUG(5,("access: %s ", ctime(&atime))); + DEBUG(5,("write: %s ", ctime(&mtime))); + DEBUG(5,("change: %s ", ctime(&mtime))); + DEBUG(5,("mode: %x\n", mode)); + break; - /* Create an smb_filename with stream_name == NULL. */ - status = - create_synthetic_smb_fname(talloc_tos(), - smb_fname->base_name, - NULL, NULL, - &smb_fname_base); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; - } + case SMB_FILE_STANDARD_INFORMATION: + case SMB_QUERY_FILE_STANDARD_INFO: - if (INFO_LEVEL_IS_UNIX(info_level)) { - /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) { - DEBUG(3,("call_trans2qfilepathinfo: " - "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname_base), - strerror(errno))); - reply_nterror(req,map_nt_error_from_unix(errno)); - TALLOC_FREE(smb_fname_base); - return; - } - } else { - if (SMB_VFS_STAT(conn, smb_fname_base) != 0) { - DEBUG(3,("call_trans2qfilepathinfo: " - "fileinfo of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname_base), - strerror(errno))); - reply_nterror(req,map_nt_error_from_unix(errno)); - TALLOC_FREE(smb_fname_base); - return; - } - } + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n")); + data_size = 24; + SOFF_T(pdata,0,allocation_size); + SOFF_T(pdata,8,file_size); + SIVAL(pdata,16,nlink); + SCVAL(pdata,20,delete_pending?1:0); + SCVAL(pdata,21,(mode&aDIR)?1:0); + SSVAL(pdata,22,0); /* Padding. */ + break; - fileid = vfs_file_id_from_sbuf(conn, - &smb_fname_base->st); - TALLOC_FREE(smb_fname_base); - get_file_infos(fileid, &delete_pending, NULL); - if (delete_pending) { - reply_nterror(req, NT_STATUS_DELETE_PENDING); - return; - } + case SMB_FILE_EA_INFORMATION: + case SMB_QUERY_FILE_EA_INFO: + { + unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); + data_size = 4; + SIVAL(pdata,0,ea_size); + break; } - if (INFO_LEVEL_IS_UNIX(info_level)) { - /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { - DEBUG(3,("call_trans2qfilepathinfo: " - "SMB_VFS_LSTAT of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req,map_nt_error_from_unix(errno)); - return; + /* Get the 8.3 name - used if NT SMB was negotiated. */ + case SMB_QUERY_FILE_ALT_NAME_INFO: + case SMB_FILE_ALTERNATE_NAME_INFORMATION: + { + int len; + char mangled_name[13]; + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n")); + if (!name_to_8_3(base_name,mangled_name, + True,conn->params)) { + return NT_STATUS_NO_MEMORY; } + len = srvstr_push(dstart, flags2, + pdata+4, mangled_name, + PTR_DIFF(dend, pdata+4), + STR_UNICODE); + data_size = 4 + len; + SIVAL(pdata,0,len); + break; + } - } else if (!VALID_STAT(smb_fname->st) && - SMB_VFS_STAT(conn, smb_fname) && - (info_level != SMB_INFO_IS_NAME_VALID)) { - ms_dfs_link = check_msdfs_link(conn, fname, - &smb_fname->st); - - if (!ms_dfs_link) { - DEBUG(3,("call_trans2qfilepathinfo: " - "SMB_VFS_STAT of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req,map_nt_error_from_unix(errno)); - return; - } + case SMB_QUERY_FILE_NAME_INFO: + { + int len; + /* + this must be *exactly* right for ACLs on mapped drives to work + */ + len = srvstr_push(dstart, flags2, + pdata+4, dos_fname, + PTR_DIFF(dend, pdata+4), + STR_UNICODE); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n")); + data_size = 4 + len; + SIVAL(pdata,0,len); + break; } - fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); - get_file_infos(fileid, &delete_pending, &write_time_ts); - if (delete_pending) { - reply_nterror(req, NT_STATUS_DELETE_PENDING); - return; + case SMB_FILE_ALLOCATION_INFORMATION: + case SMB_QUERY_FILE_ALLOCATION_INFO: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n")); + data_size = 8; + SOFF_T(pdata,0,allocation_size); + break; + + case SMB_FILE_END_OF_FILE_INFORMATION: + case SMB_QUERY_FILE_END_OF_FILEINFO: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n")); + data_size = 8; + SOFF_T(pdata,0,file_size); + break; + + case SMB_QUERY_FILE_ALL_INFO: + case SMB_FILE_ALL_INFORMATION: + { + int len; + unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n")); + put_long_date_timespec(pdata,create_time_ts); + put_long_date_timespec(pdata+8,atime_ts); + put_long_date_timespec(pdata+16,mtime_ts); /* write time */ + put_long_date_timespec(pdata+24,mtime_ts); /* change time */ + SIVAL(pdata,32,mode); + SIVAL(pdata,36,0); /* padding. */ + pdata += 40; + SOFF_T(pdata,0,allocation_size); + SOFF_T(pdata,8,file_size); + SIVAL(pdata,16,nlink); + SCVAL(pdata,20,delete_pending); + SCVAL(pdata,21,(mode&aDIR)?1:0); + SSVAL(pdata,22,0); + pdata += 24; + SIVAL(pdata,0,ea_size); + pdata += 4; /* EA info */ + len = srvstr_push(dstart, flags2, + pdata+4, dos_fname, + PTR_DIFF(dend, pdata+4), + STR_UNICODE); + SIVAL(pdata,0,len); + pdata += 4 + len; + data_size = PTR_DIFF(pdata,(*ppdata)); + break; } - } + case SMB_FILE_INTERNAL_INFORMATION: + /* This should be an index number - looks like + dev/ino to me :-) - /* Set sbuf for use below. */ - sbuf = smb_fname->st; + I think this causes us to fail the IFSKIT + BasicFileInformationTest. -tpot */ - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; - } + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); + SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */ + SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */ + data_size = 8; + break; - DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n", - fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data)); + case SMB_FILE_ACCESS_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); + if (fsp) { + SIVAL(pdata,0,fsp->access_mask); + } else { + /* GENERIC_EXECUTE mapping from Windows */ + SIVAL(pdata,0,0x12019F); + } + data_size = 4; + break; - p = strrchr_m(smb_fname->base_name,'/'); - if (!p) - base_name = smb_fname->base_name; - else - base_name = p+1; + case SMB_FILE_NAME_INFORMATION: + /* Pathname with leading '\'. */ + { + size_t byte_len; + byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n")); + SIVAL(pdata,0,byte_len); + data_size = 4 + byte_len; + break; + } - if (ms_dfs_link) { - mode = dos_mode_msdfs(conn, smb_fname); - } else { - mode = dos_mode(conn, smb_fname); - } - if (!mode) - mode = FILE_ATTRIBUTE_NORMAL; + case SMB_FILE_DISPOSITION_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n")); + data_size = 1; + SCVAL(pdata,0,delete_pending); + break; - nlink = sbuf.st_ex_nlink; + case SMB_FILE_POSITION_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n")); + data_size = 8; + SOFF_T(pdata,0,pos); + break; - if (nlink && (mode&aDIR)) { - nlink = 1; - } + case SMB_FILE_MODE_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n")); + SIVAL(pdata,0,mode); + data_size = 4; + break; - if ((nlink > 0) && delete_pending) { - nlink -= 1; - } + case SMB_FILE_ALIGNMENT_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n")); + SIVAL(pdata,0,0); /* No alignment needed. */ + data_size = 4; + break; + + /* + * NT4 server just returns "invalid query" to this - if we try + * to answer it then NTws gets a BSOD! (tridge). W2K seems to + * want this. JRA. + */ + /* The first statement above is false - verified using Thursby + * client against NT4 -- gcolley. + */ + case SMB_QUERY_FILE_STREAM_INFO: + case SMB_FILE_STREAM_INFORMATION: { + unsigned int num_streams; + struct stream_struct *streams; - fullpathname = fname; - if (!(mode & aDIR)) - file_size = get_file_size_stat(&sbuf); + DEBUG(10,("smbd_do_qfilepathinfo: " + "SMB_FILE_STREAM_INFORMATION\n")); - /* Pull out any data sent here before we realloc. */ - switch (info_level) { - case SMB_INFO_QUERY_EAS_FROM_LIST: - { - /* Pull any EA list from the data portion. */ - uint32 ea_size; + status = SMB_VFS_STREAMINFO( + conn, fsp, fname, talloc_tos(), + &num_streams, &streams); - if (total_data < 4) { - reply_nterror( - req, NT_STATUS_INVALID_PARAMETER); - return; + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("could not get stream info: %s\n", + nt_errstr(status))); + return status; } - ea_size = IVAL(pdata,0); - if (total_data > 0 && ea_size != total_data) { - DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \ -total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) )); - reply_nterror( - req, NT_STATUS_INVALID_PARAMETER); - return; - } + status = marshall_stream_info(num_streams, streams, + pdata, max_data_bytes, + &data_size); - if (!lp_ea_support(SNUM(conn))) { - reply_doserror(req, ERRDOS, - ERReasnotsupported); - return; + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("marshall_stream_info failed: %s\n", + nt_errstr(status))); + return status; } - /* Pull out the list of names. */ - ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4); - if (!ea_list) { - reply_nterror( - req, NT_STATUS_INVALID_PARAMETER); - return; - } + TALLOC_FREE(streams); + break; } + case SMB_QUERY_COMPRESSION_INFO: + case SMB_FILE_COMPRESSION_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n")); + SOFF_T(pdata,0,file_size); + SIVAL(pdata,8,0); /* ??? */ + SIVAL(pdata,12,0); /* ??? */ + data_size = 16; + break; - case SMB_QUERY_POSIX_LOCK: - { - if (fsp == NULL || fsp->fh->fd == -1) { - reply_nterror(req, NT_STATUS_INVALID_HANDLE); - return; - } - - if (total_data != POSIX_LOCK_DATA_SIZE) { - reply_nterror( - req, NT_STATUS_INVALID_PARAMETER); - return; - } + case SMB_FILE_NETWORK_OPEN_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n")); + put_long_date_timespec(pdata,create_time_ts); + put_long_date_timespec(pdata+8,atime_ts); + put_long_date_timespec(pdata+16,mtime_ts); /* write time */ + put_long_date_timespec(pdata+24,mtime_ts); /* change time */ + SOFF_T(pdata,32,allocation_size); + SOFF_T(pdata,40,file_size); + SIVAL(pdata,48,mode); + SIVAL(pdata,52,0); /* ??? */ + data_size = 56; + break; - /* Copy the lock range data. */ - lock_data = (char *)TALLOC_MEMDUP( - ctx, pdata, total_data); - if (!lock_data) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - } - default: + case SMB_FILE_ATTRIBUTE_TAG_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n")); + SIVAL(pdata,0,mode); + SIVAL(pdata,4,0); + data_size = 8; break; - } - *pparams = (char *)SMB_REALLOC(*pparams,2); - if (*pparams == NULL) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - params = *pparams; - SSVAL(params,0,0); - data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN; - *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); - if (*ppdata == NULL ) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - pdata = *ppdata; - dstart = pdata; - dend = dstart + data_size - 1; + /* + * CIFS UNIX Extensions. + */ - allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf); + case SMB_QUERY_FILE_UNIX_BASIC: - if (!fsp) { - /* Do we have this path open ? */ - files_struct *fsp1; - fileid = vfs_file_id_from_sbuf(conn, &sbuf); - fsp1 = file_find_di_first(fileid); - if (fsp1 && fsp1->initial_allocation_size) { - allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf); - } - } + pdata = store_file_unix_basic(conn, pdata, fsp, &sbuf); + data_size = PTR_DIFF(pdata,(*ppdata)); - if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) { - update_stat_ex_mtime(&sbuf, write_time_ts); - } + { + int i; + DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC ")); - create_time_ts = sbuf.st_ex_btime; - mtime_ts = sbuf.st_ex_mtime; - atime_ts = sbuf.st_ex_atime; + for (i=0; i<100; i++) + DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); + DEBUG(4,("\n")); + } - if (lp_dos_filetime_resolution(SNUM(conn))) { - dos_filetime_timespec(&create_time_ts); - dos_filetime_timespec(&mtime_ts); - dos_filetime_timespec(&atime_ts); - } + break; - create_time = convert_timespec_to_time_t(create_time_ts); - mtime = convert_timespec_to_time_t(mtime_ts); - atime = convert_timespec_to_time_t(atime_ts); + case SMB_QUERY_FILE_UNIX_INFO2: - /* NT expects the name to be in an exact form of the *full* - filename. See the trans2 torture test */ - if (ISDOT(base_name)) { - dos_fname = talloc_strdup(ctx, "\\"); - if (!dos_fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - } else { - dos_fname = talloc_asprintf(ctx, - "\\%s", - fname); - if (!dos_fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - string_replace(dos_fname, '/', '\\'); - } + pdata = store_file_unix_basic_info2(conn, pdata, fsp, &sbuf); + data_size = PTR_DIFF(pdata,(*ppdata)); - switch (info_level) { - case SMB_INFO_STANDARD: - DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n")); - data_size = 22; - srv_put_dos_date2(pdata,l1_fdateCreation,create_time); - srv_put_dos_date2(pdata,l1_fdateLastAccess,atime); - srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */ - SIVAL(pdata,l1_cbFile,(uint32)file_size); - SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size); - SSVAL(pdata,l1_attrFile,mode); - break; + { + int i; + DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 ")); + + for (i=0; i<100; i++) + DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); + DEBUG(4,("\n")); + } - case SMB_INFO_QUERY_EA_SIZE: - { - unsigned int ea_size = estimate_ea_size(conn, fsp, fname); - DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n")); - data_size = 26; - srv_put_dos_date2(pdata,0,create_time); - srv_put_dos_date2(pdata,4,atime); - srv_put_dos_date2(pdata,8,mtime); /* write time */ - SIVAL(pdata,12,(uint32)file_size); - SIVAL(pdata,16,(uint32)allocation_size); - SSVAL(pdata,20,mode); - SIVAL(pdata,22,ea_size); break; - } - case SMB_INFO_IS_NAME_VALID: - DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n")); - if (tran_call == TRANSACT2_QFILEINFO) { - /* os/2 needs this ? really ?*/ - reply_doserror(req, ERRDOS, ERRbadfunc); - return; + case SMB_QUERY_FILE_UNIX_LINK: + { + int len; + char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1); + + if (!buffer) { + return NT_STATUS_NO_MEMORY; + } + + DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n")); +#ifdef S_ISLNK + if(!S_ISLNK(sbuf.st_ex_mode)) { + return NT_STATUS_DOS(ERRSRV, ERRbadlink); + } +#else + return NT_STATUS_DOS(ERRDOS, ERRbadlink); +#endif + len = SMB_VFS_READLINK(conn,fname, + buffer, PATH_MAX); + if (len == -1) { + return map_nt_error_from_unix(errno); + } + buffer[len] = 0; + len = srvstr_push(dstart, flags2, + pdata, buffer, + PTR_DIFF(dend, pdata), + STR_TERMINATE); + pdata += len; + data_size = PTR_DIFF(pdata,(*ppdata)); + + break; } - data_size = 0; - param_size = 0; - break; - case SMB_INFO_QUERY_EAS_FROM_LIST: - { - size_t total_ea_len = 0; - struct ea_list *ea_file_list = NULL; +#if defined(HAVE_POSIX_ACLS) + case SMB_QUERY_POSIX_ACL: + { + SMB_ACL_T file_acl = NULL; + SMB_ACL_T def_acl = NULL; + uint16 num_file_acls = 0; + uint16 num_def_acls = 0; + + if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) { + file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); + } else { + file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS); + } + + if (file_acl == NULL && no_acl_syscall_error(errno)) { + DEBUG(5,("smbd_do_qfilepathinfo: ACLs not implemented on filesystem containing %s\n", + fname )); + return NT_STATUS_NOT_IMPLEMENTED; + } + + if (S_ISDIR(sbuf.st_ex_mode)) { + if (fsp && fsp->is_directory) { + def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); + } else { + def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT); + } + def_acl = free_empty_sys_acl(conn, def_acl); + } + + num_file_acls = count_acl_entries(conn, file_acl); + num_def_acls = count_acl_entries(conn, def_acl); - DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n")); + if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) { + DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n", + data_size, + (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + + SMB_POSIX_ACL_HEADER_SIZE) )); + if (file_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); + } + if (def_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); + } + return NT_STATUS_BUFFER_TOO_SMALL; + } - ea_file_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len); - ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len); + SSVAL(pdata,0,SMB_POSIX_ACL_VERSION); + SSVAL(pdata,2,num_file_acls); + SSVAL(pdata,4,num_def_acls); + if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) { + if (file_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); + } + if (def_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); + } + return NT_STATUS_INTERNAL_ERROR; + } + if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) { + if (file_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); + } + if (def_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); + } + return NT_STATUS_INTERNAL_ERROR; + } - if (!ea_list || (total_ea_len > data_size)) { - data_size = 4; - SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ + if (file_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); + } + if (def_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); + } + data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE; break; } +#endif - data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list); - break; - } - case SMB_INFO_QUERY_ALL_EAS: + case SMB_QUERY_POSIX_LOCK: { - /* We have data_size bytes to put EA's into. */ - size_t total_ea_len = 0; - - DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n")); + uint64_t count; + uint64_t offset; + uint32 lock_pid; + enum brl_type lock_type; - ea_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len); - if (!ea_list || (total_ea_len > data_size)) { - data_size = 4; - SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ - break; + if (lock_data_count != POSIX_LOCK_DATA_SIZE) { + return NT_STATUS_INVALID_PARAMETER; } - data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list); - break; - } - - case SMB_FILE_BASIC_INFORMATION: - case SMB_QUERY_FILE_BASIC_INFO: - - if (info_level == SMB_QUERY_FILE_BASIC_INFO) { - DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n")); - data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */ - } else { - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n")); - data_size = 40; - SIVAL(pdata,36,0); + switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) { + case POSIX_LOCK_TYPE_READ: + lock_type = READ_LOCK; + break; + case POSIX_LOCK_TYPE_WRITE: + lock_type = WRITE_LOCK; + break; + case POSIX_LOCK_TYPE_UNLOCK: + default: + /* There's no point in asking for an unlock... */ + return NT_STATUS_INVALID_PARAMETER; } - put_long_date_timespec(pdata,create_time_ts); - put_long_date_timespec(pdata+8,atime_ts); - put_long_date_timespec(pdata+16,mtime_ts); /* write time */ - put_long_date_timespec(pdata+24,mtime_ts); /* change time */ - SIVAL(pdata,32,mode); - DEBUG(5,("SMB_QFBI - ")); - DEBUG(5,("create: %s ", ctime(&create_time))); - DEBUG(5,("access: %s ", ctime(&atime))); - DEBUG(5,("write: %s ", ctime(&mtime))); - DEBUG(5,("change: %s ", ctime(&mtime))); - DEBUG(5,("mode: %x\n", mode)); - break; + lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET); +#if defined(HAVE_LONGLONG) + offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | + ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET)); + count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) | + ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET)); +#else /* HAVE_LONGLONG */ + offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET); + count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET); +#endif /* HAVE_LONGLONG */ - case SMB_FILE_STANDARD_INFORMATION: - case SMB_QUERY_FILE_STANDARD_INFO: + status = query_lock(fsp, + &lock_pid, + &count, + &offset, + &lock_type, + POSIX_LOCK); - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n")); - data_size = 24; - SOFF_T(pdata,0,allocation_size); - SOFF_T(pdata,8,file_size); - SIVAL(pdata,16,nlink); - SCVAL(pdata,20,delete_pending?1:0); - SCVAL(pdata,21,(mode&aDIR)?1:0); - SSVAL(pdata,22,0); /* Padding. */ - break; + if (ERROR_WAS_LOCK_DENIED(status)) { + /* Here we need to report who has it locked... */ + data_size = POSIX_LOCK_DATA_SIZE; - case SMB_FILE_EA_INFORMATION: - case SMB_QUERY_FILE_EA_INFO: - { - unsigned int ea_size = estimate_ea_size(conn, fsp, fname); - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); - data_size = 4; - SIVAL(pdata,0,ea_size); - break; - } + SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type); + SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0); + SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid); +#if defined(HAVE_LONGLONG) + SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF)); + SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF)); + SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF)); + SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF)); +#else /* HAVE_LONGLONG */ + SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset); + SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count); +#endif /* HAVE_LONGLONG */ - /* Get the 8.3 name - used if NT SMB was negotiated. */ - case SMB_QUERY_FILE_ALT_NAME_INFO: - case SMB_FILE_ALTERNATE_NAME_INFORMATION: - { - char mangled_name[13]; - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n")); - if (!name_to_8_3(base_name,mangled_name, - True,conn->params)) { - reply_nterror( - req, - NT_STATUS_NO_MEMORY); - return; + } else if (NT_STATUS_IS_OK(status)) { + /* For success we just return a copy of what we sent + with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */ + data_size = POSIX_LOCK_DATA_SIZE; + memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE); + SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK); + } else { + return status; } - len = srvstr_push(dstart, req->flags2, - pdata+4, mangled_name, - PTR_DIFF(dend, pdata+4), - STR_UNICODE); - data_size = 4 + len; - SIVAL(pdata,0,len); break; } - case SMB_QUERY_FILE_NAME_INFO: - /* - this must be *exactly* right for ACLs on mapped drives to work - */ - len = srvstr_push(dstart, req->flags2, - pdata+4, dos_fname, - PTR_DIFF(dend, pdata+4), - STR_UNICODE); - DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n")); - data_size = 4 + len; - SIVAL(pdata,0,len); - break; + default: + return NT_STATUS_INVALID_LEVEL; + } - case SMB_FILE_ALLOCATION_INFORMATION: - case SMB_QUERY_FILE_ALLOCATION_INFO: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n")); - data_size = 8; - SOFF_T(pdata,0,allocation_size); - break; + *pdata_size = data_size; + return NT_STATUS_OK; +} - case SMB_FILE_END_OF_FILE_INFORMATION: - case SMB_QUERY_FILE_END_OF_FILEINFO: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n")); - data_size = 8; - SOFF_T(pdata,0,file_size); - break; +/**************************************************************************** + Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by + file name or file id). +****************************************************************************/ - case SMB_QUERY_FILE_ALL_INFO: - case SMB_FILE_ALL_INFORMATION: - { - unsigned int ea_size = estimate_ea_size(conn, fsp, fname); - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n")); - put_long_date_timespec(pdata,create_time_ts); - put_long_date_timespec(pdata+8,atime_ts); - put_long_date_timespec(pdata+16,mtime_ts); /* write time */ - put_long_date_timespec(pdata+24,mtime_ts); /* change time */ - SIVAL(pdata,32,mode); - SIVAL(pdata,36,0); /* padding. */ - pdata += 40; - SOFF_T(pdata,0,allocation_size); - SOFF_T(pdata,8,file_size); - SIVAL(pdata,16,nlink); - SCVAL(pdata,20,delete_pending); - SCVAL(pdata,21,(mode&aDIR)?1:0); - SSVAL(pdata,22,0); - pdata += 24; - SIVAL(pdata,0,ea_size); - pdata += 4; /* EA info */ - len = srvstr_push(dstart, req->flags2, - pdata+4, dos_fname, - PTR_DIFF(dend, pdata+4), - STR_UNICODE); - SIVAL(pdata,0,len); - pdata += 4 + len; - data_size = PTR_DIFF(pdata,(*ppdata)); - break; - } - case SMB_FILE_INTERNAL_INFORMATION: - /* This should be an index number - looks like - dev/ino to me :-) +static void call_trans2qfilepathinfo(connection_struct *conn, + struct smb_request *req, + unsigned int tran_call, + char **pparams, int total_params, + char **ppdata, int total_data, + unsigned int max_data_bytes) +{ + char *params = *pparams; + char *pdata = *ppdata; + uint16 info_level; + unsigned int data_size = 0; + unsigned int param_size = 2; + char *fname = NULL; + struct smb_filename *smb_fname = NULL; + bool delete_pending = False; + struct timespec write_time_ts; + files_struct *fsp = NULL; + struct file_id fileid; + struct ea_list *ea_list = NULL; + int lock_data_count = 0; + char *lock_data = NULL; + bool ms_dfs_link = false; + NTSTATUS status = NT_STATUS_OK; - I think this causes us to fail the IFSKIT - BasicFileInformationTest. -tpot */ + if (!params) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); - SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */ - SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */ - data_size = 8; - break; + ZERO_STRUCT(write_time_ts); + + if (tran_call == TRANSACT2_QFILEINFO) { + if (total_params < 4) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } - case SMB_FILE_ACCESS_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); - if (fsp) { - SIVAL(pdata,0,fsp->access_mask); - } else { - /* GENERIC_EXECUTE mapping from Windows */ - SIVAL(pdata,0,0x12019F); - } - data_size = 4; - break; + if (IS_IPC(conn)) { + call_trans2qpipeinfo(conn, req, tran_call, + pparams, total_params, + ppdata, total_data, + max_data_bytes); + return; + } - case SMB_FILE_NAME_INFORMATION: - /* Pathname with leading '\'. */ - { - size_t byte_len; - byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False); - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n")); - SIVAL(pdata,0,byte_len); - data_size = 4 + byte_len; - break; - } + fsp = file_fsp(req, SVAL(params,0)); + info_level = SVAL(params,2); - case SMB_FILE_DISPOSITION_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n")); - data_size = 1; - SCVAL(pdata,0,delete_pending); - break; + DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); - case SMB_FILE_POSITION_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n")); - data_size = 8; - SOFF_T(pdata,0,pos); - break; + if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } - case SMB_FILE_MODE_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n")); - SIVAL(pdata,0,mode); - data_size = 4; - break; + /* Initial check for valid fsp ptr. */ + if (!check_fsp_open(conn, req, fsp)) { + return; + } - case SMB_FILE_ALIGNMENT_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n")); - SIVAL(pdata,0,0); /* No alignment needed. */ - data_size = 4; - break; + fname = talloc_strdup(talloc_tos(),fsp->fsp_name); + if (!fname) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } - /* - * NT4 server just returns "invalid query" to this - if we try - * to answer it then NTws gets a BSOD! (tridge). W2K seems to - * want this. JRA. - */ - /* The first statement above is false - verified using Thursby - * client against NT4 -- gcolley. - */ - case SMB_QUERY_FILE_STREAM_INFO: - case SMB_FILE_STREAM_INFORMATION: { - unsigned int num_streams; - struct stream_struct *streams; + status = create_synthetic_smb_fname_split(talloc_tos(), fname, + NULL, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } - DEBUG(10,("call_trans2qfilepathinfo: " - "SMB_FILE_STREAM_INFORMATION\n")); + if(fsp->fake_file_handle) { + /* + * This is actually for the QUOTA_FAKE_FILE --metze + */ - status = SMB_VFS_STREAMINFO( - conn, fsp, fname, talloc_tos(), - &num_streams, &streams); + /* We know this name is ok, it's already passed the checks. */ - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("could not get stream info: %s\n", - nt_errstr(status))); - reply_nterror(req, status); + } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) { + /* + * This is actually a QFILEINFO on a directory + * handle (returned from an NT SMB). NT5.0 seems + * to do this call. JRA. + */ + + if (INFO_LEVEL_IS_UNIX(info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname)) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_LSTAT of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, + map_nt_error_from_unix(errno)); + return; + } + } else if (SMB_VFS_STAT(conn, smb_fname)) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_STAT of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, + map_nt_error_from_unix(errno)); return; } - status = marshall_stream_info(num_streams, streams, - pdata, max_data_bytes, - &data_size); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("marshall_stream_info failed: %s\n", - nt_errstr(status))); - reply_nterror(req, status); + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, &delete_pending, &write_time_ts); + } else { + /* + * Original code - this is an open file. + */ + if (!check_fsp(conn, req, fsp)) { return; } - TALLOC_FREE(streams); - - break; + if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + DEBUG(3, ("fstat of fnum %d failed (%s)\n", + fsp->fnum, strerror(errno))); + reply_nterror(req, + map_nt_error_from_unix(errno)); + return; + } + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, &delete_pending, &write_time_ts); } - case SMB_QUERY_COMPRESSION_INFO: - case SMB_FILE_COMPRESSION_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n")); - SOFF_T(pdata,0,file_size); - SIVAL(pdata,8,0); /* ??? */ - SIVAL(pdata,12,0); /* ??? */ - data_size = 16; - break; - case SMB_FILE_NETWORK_OPEN_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n")); - put_long_date_timespec(pdata,create_time_ts); - put_long_date_timespec(pdata+8,atime_ts); - put_long_date_timespec(pdata+16,mtime_ts); /* write time */ - put_long_date_timespec(pdata+24,mtime_ts); /* change time */ - SOFF_T(pdata,32,allocation_size); - SOFF_T(pdata,40,file_size); - SIVAL(pdata,48,mode); - SIVAL(pdata,52,0); /* ??? */ - data_size = 56; - break; - - case SMB_FILE_ATTRIBUTE_TAG_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n")); - SIVAL(pdata,0,mode); - SIVAL(pdata,4,0); - data_size = 8; - break; + } else { + /* qpathinfo */ + if (total_params < 7) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } - /* - * CIFS UNIX Extensions. - */ + info_level = SVAL(params,0); - case SMB_QUERY_FILE_UNIX_BASIC: + DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level)); - pdata = store_file_unix_basic(conn, pdata, fsp, &sbuf); - data_size = PTR_DIFF(pdata,(*ppdata)); + if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } - { - int i; - DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC ")); + srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6], + total_params - 6, + STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } - for (i=0; i<100; i++) - DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); - DEBUG(4,("\n")); + status = filename_convert(req, + conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + &smb_fname, + &fname); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + return; } + reply_nterror(req, status); + return; + } - break; - - case SMB_QUERY_FILE_UNIX_INFO2: - - pdata = store_file_unix_basic_info2(conn, pdata, fsp, &sbuf); - data_size = PTR_DIFF(pdata,(*ppdata)); - - { - int i; - DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 ")); + /* If this is a stream, check if there is a delete_pending. */ + if ((conn->fs_capabilities & FILE_NAMED_STREAMS) + && is_ntfs_stream_smb_fname(smb_fname)) { + struct smb_filename *smb_fname_base = NULL; - for (i=0; i<100; i++) - DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); - DEBUG(4,("\n")); + /* Create an smb_filename with stream_name == NULL. */ + status = + create_synthetic_smb_fname(talloc_tos(), + smb_fname->base_name, + NULL, NULL, + &smb_fname_base); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; } - break; - - case SMB_QUERY_FILE_UNIX_LINK: - { - char *buffer = TALLOC_ARRAY(ctx, char, PATH_MAX+1); - - if (!buffer) { - reply_nterror(req, NT_STATUS_NO_MEMORY); + if (INFO_LEVEL_IS_UNIX(info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_LSTAT of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname_base), + strerror(errno))); + TALLOC_FREE(smb_fname_base); + reply_nterror(req, + map_nt_error_from_unix(errno)); return; } - - DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n")); -#ifdef S_ISLNK - if(!S_ISLNK(sbuf.st_ex_mode)) { - reply_doserror(req, ERRSRV, - ERRbadlink); + } else { + if (SMB_VFS_STAT(conn, smb_fname_base) != 0) { + DEBUG(3,("call_trans2qfilepathinfo: " + "fileinfo of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname_base), + strerror(errno))); + TALLOC_FREE(smb_fname_base); + reply_nterror(req, + map_nt_error_from_unix(errno)); return; } -#else - reply_doserror(req, ERRDOS, ERRbadlink); + } + + fileid = vfs_file_id_from_sbuf(conn, + &smb_fname_base->st); + TALLOC_FREE(smb_fname_base); + get_file_infos(fileid, &delete_pending, NULL); + if (delete_pending) { + reply_nterror(req, NT_STATUS_DELETE_PENDING); return; -#endif - len = SMB_VFS_READLINK(conn,fullpathname, - buffer, PATH_MAX); - if (len == -1) { - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } - buffer[len] = 0; - len = srvstr_push(dstart, req->flags2, - pdata, buffer, - PTR_DIFF(dend, pdata), - STR_TERMINATE); - pdata += len; - data_size = PTR_DIFF(pdata,(*ppdata)); + } + } - break; + if (INFO_LEVEL_IS_UNIX(info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname)) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_LSTAT of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, + map_nt_error_from_unix(errno)); + return; } -#if defined(HAVE_POSIX_ACLS) - case SMB_QUERY_POSIX_ACL: - { - SMB_ACL_T file_acl = NULL; - SMB_ACL_T def_acl = NULL; - uint16 num_file_acls = 0; - uint16 num_def_acls = 0; + } else if (!VALID_STAT(smb_fname->st) && + SMB_VFS_STAT(conn, smb_fname) && + (info_level != SMB_INFO_IS_NAME_VALID)) { + ms_dfs_link = check_msdfs_link(conn, fname, + &smb_fname->st); - if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) { - file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); - } else { - file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS); - } + if (!ms_dfs_link) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_STAT of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, + map_nt_error_from_unix(errno)); + return; + } + } - if (file_acl == NULL && no_acl_syscall_error(errno)) { - DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n", - fname )); - reply_nterror( - req, - NT_STATUS_NOT_IMPLEMENTED); - return; - } + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, &delete_pending, &write_time_ts); + if (delete_pending) { + reply_nterror(req, NT_STATUS_DELETE_PENDING); + return; + } + } - if (S_ISDIR(sbuf.st_ex_mode)) { - if (fsp && fsp->is_directory) { - def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); - } else { - def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT); - } - def_acl = free_empty_sys_acl(conn, def_acl); - } + DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n", + fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data)); - num_file_acls = count_acl_entries(conn, file_acl); - num_def_acls = count_acl_entries(conn, def_acl); + /* Pull out any data sent here before we realloc. */ + switch (info_level) { + case SMB_INFO_QUERY_EAS_FROM_LIST: + { + /* Pull any EA list from the data portion. */ + uint32 ea_size; - if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) { - DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n", - data_size, - (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + - SMB_POSIX_ACL_HEADER_SIZE) )); - if (file_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); - } - if (def_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); - } - reply_nterror( - req, - NT_STATUS_BUFFER_TOO_SMALL); - return; - } + if (total_data < 4) { + reply_nterror( + req, NT_STATUS_INVALID_PARAMETER); + return; + } + ea_size = IVAL(pdata,0); - SSVAL(pdata,0,SMB_POSIX_ACL_VERSION); - SSVAL(pdata,2,num_file_acls); - SSVAL(pdata,4,num_def_acls); - if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) { - if (file_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); - } - if (def_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); - } - reply_nterror( - req, NT_STATUS_INTERNAL_ERROR); - return; - } - if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) { - if (file_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); - } - if (def_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); - } - reply_nterror( - req, - NT_STATUS_INTERNAL_ERROR); - return; - } + if (total_data > 0 && ea_size != total_data) { + DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \ +total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) )); + reply_nterror( + req, NT_STATUS_INVALID_PARAMETER); + return; + } - if (file_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); - } - if (def_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); - } - data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE; - break; + if (!lp_ea_support(SNUM(conn))) { + reply_doserror(req, ERRDOS, + ERReasnotsupported); + return; } -#endif + /* Pull out the list of names. */ + ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4); + if (!ea_list) { + reply_nterror( + req, NT_STATUS_INVALID_PARAMETER); + return; + } + break; + } case SMB_QUERY_POSIX_LOCK: { - uint64_t count; - uint64_t offset; - uint32 lock_pid; - enum brl_type lock_type; + if (fsp == NULL || fsp->fh->fd == -1) { + reply_nterror(req, NT_STATUS_INVALID_HANDLE); + return; + } if (total_data != POSIX_LOCK_DATA_SIZE) { reply_nterror( @@ -4830,73 +4893,55 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd return; } - switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) { - case POSIX_LOCK_TYPE_READ: - lock_type = READ_LOCK; - break; - case POSIX_LOCK_TYPE_WRITE: - lock_type = WRITE_LOCK; - break; - case POSIX_LOCK_TYPE_UNLOCK: - default: - /* There's no point in asking for an unlock... */ - reply_nterror( - req, - NT_STATUS_INVALID_PARAMETER); - return; - } - - lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET); -#if defined(HAVE_LONGLONG) - offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | - ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET)); - count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) | - ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET)); -#else /* HAVE_LONGLONG */ - offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET); - count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET); -#endif /* HAVE_LONGLONG */ - - status = query_lock(fsp, - &lock_pid, - &count, - &offset, - &lock_type, - POSIX_LOCK); - - if (ERROR_WAS_LOCK_DENIED(status)) { - /* Here we need to report who has it locked... */ - data_size = POSIX_LOCK_DATA_SIZE; - - SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type); - SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0); - SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid); -#if defined(HAVE_LONGLONG) - SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF)); - SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF)); - SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF)); - SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF)); -#else /* HAVE_LONGLONG */ - SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset); - SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count); -#endif /* HAVE_LONGLONG */ - - } else if (NT_STATUS_IS_OK(status)) { - /* For success we just return a copy of what we sent - with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */ - data_size = POSIX_LOCK_DATA_SIZE; - memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE); - SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK); - } else { - reply_nterror(req, status); + /* Copy the lock range data. */ + lock_data = (char *)TALLOC_MEMDUP( + req, pdata, total_data); + if (!lock_data) { + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } - break; + lock_data_count = total_data; } - default: - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + break; + } + + *pparams = (char *)SMB_REALLOC(*pparams,2); + if (*pparams == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + params = *pparams; + SSVAL(params,0,0); + + /* + * draft-leach-cifs-v1-spec-02.txt + * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path + * says: + * + * The requested information is placed in the Data portion of the + * transaction response. For the information levels greater than 0x100, + * the transaction response has 1 parameter word which should be + * ignored by the client. + * + * However Windows only follows this rule for the IS_NAME_VALID call. + */ + switch (info_level) { + case SMB_INFO_IS_NAME_VALID: + param_size = 0; + break; + } + + status = smbd_do_qfilepathinfo(conn, req, info_level, + fsp, smb_fname, + delete_pending, write_time_ts, + ms_dfs_link, ea_list, + lock_data_count, lock_data, + req->flags2, max_data_bytes, + ppdata, &data_size); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; } send_trans2_replies(conn, req, params, param_size, *ppdata, data_size, -- cgit From ee690df294aab7a738bfec1976a2f015e918db1e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Jul 2009 16:37:49 +0200 Subject: s3:smbd: split calculation and mashalling of file index and access_mask metze --- source3/smbd/trans2.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index c9e7e4bbfb..757e5f5c8b 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3910,6 +3910,8 @@ static NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, uint64_t file_size = 0; uint64_t pos = 0; uint64_t allocation_size = 0; + uint64_t file_index = 0; + uint32_t access_mask = 0; sbuf = smb_fname->st; @@ -4013,6 +4015,21 @@ static NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, pos = fsp->fh->position_information; } + if (fsp) { + access_mask = fsp->access_mask; + } else { + /* GENERIC_EXECUTE mapping from Windows */ + access_mask = 0x12019F; + } + + /* This should be an index number - looks like + dev/ino to me :-) + + I think this causes us to fail the IFSKIT + BasicFileInformationTest. -tpot */ + file_index = ((sbuf.st_ex_ino) & UINT32_MAX); /* FileIndexLow */ + file_index |= ((sbuf.st_ex_dev) & UINT32_MAX) << 32; /* FileIndexHigh */ + switch (info_level) { case SMB_INFO_STANDARD: DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n")); @@ -4218,26 +4235,15 @@ static NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, break; } case SMB_FILE_INTERNAL_INFORMATION: - /* This should be an index number - looks like - dev/ino to me :-) - - I think this causes us to fail the IFSKIT - BasicFileInformationTest. -tpot */ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); - SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */ - SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */ + SBVAL(pdata, 0, file_index); data_size = 8; break; case SMB_FILE_ACCESS_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); - if (fsp) { - SIVAL(pdata,0,fsp->access_mask); - } else { - /* GENERIC_EXECUTE mapping from Windows */ - SIVAL(pdata,0,0x12019F); - } + SIVAL(pdata, 0, access_mask); data_size = 4; break; -- cgit From 0ba532e1b2dedea3c07fa55631fac0d9a5032fcf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2009 20:02:44 +0200 Subject: s3:smbd: make smbd_do_qfilepathinfo() non static for use in SMB2 metze --- source3/smbd/globals.h | 16 ++++++++++++++++ source3/smbd/trans2.c | 30 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 8163213dd0..725a94a90b 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -185,6 +185,22 @@ NTSTATUS smbd_do_locking(struct smb_request *req, struct smbd_lock_element *locks, bool *async); +NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + const struct smb_filename *smb_fname, + bool delete_pending, + struct timespec write_time_ts, + bool ms_dfs_link, + struct ea_list *ea_list, + int lock_data_count, + char *lock_data, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + unsigned int *pdata_size); + void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn, const char *reason, const char *location); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 757e5f5c8b..29abbfe3f5 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3878,21 +3878,21 @@ static void call_trans2qpipeinfo(connection_struct *conn, return; } -static NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, - TALLOC_CTX *mem_ctx, - uint16_t info_level, - files_struct *fsp, - const struct smb_filename *smb_fname, - bool delete_pending, - struct timespec write_time_ts, - bool ms_dfs_link, - struct ea_list *ea_list, - int lock_data_count, - char *lock_data, - uint16_t flags2, - unsigned int max_data_bytes, - char **ppdata, - unsigned int *pdata_size) +NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + const struct smb_filename *smb_fname, + bool delete_pending, + struct timespec write_time_ts, + bool ms_dfs_link, + struct ea_list *ea_list, + int lock_data_count, + char *lock_data, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + unsigned int *pdata_size) { char *pdata = *ppdata; char *dstart, *dend; -- cgit From 0851d73f4dbb916b6e83d89cf2e2959c1159b7e0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Jul 2009 17:06:05 +0200 Subject: s3:smbd: filter out SMB2 specific private query info levels for SMB1 metze --- source3/smbd/trans2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 29abbfe3f5..96265861f2 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4938,6 +4938,15 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd break; } + if ((info_level & 0xFF00) == 0xFF00) { + /* + * We use levels that start with 0xFF00 + * internally to represent SMB2 specific levels + */ + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } + status = smbd_do_qfilepathinfo(conn, req, info_level, fsp, smb_fname, delete_pending, write_time_ts, -- cgit From e9865150dfd9a81fdc3a8b13b086540641fb4c2e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Jul 2009 17:08:18 +0200 Subject: s3:smbd: add support for marshalling SMB2 FileAllInformation metze --- source3/smbd/trans2.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 96265861f2..f13c2f0338 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4234,6 +4234,42 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, data_size = PTR_DIFF(pdata,(*ppdata)); break; } + + case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/ + { + int len; + unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n")); + put_long_date_timespec(pdata+0x00,create_time_ts); + put_long_date_timespec(pdata+0x08,atime_ts); + put_long_date_timespec(pdata+0x10,mtime_ts); /* write time */ + put_long_date_timespec(pdata+0x18,mtime_ts); /* change time */ + SIVAL(pdata, 0x20, mode); + SIVAL(pdata, 0x24, 0); /* padding. */ + SBVAL(pdata, 0x28, allocation_size); + SBVAL(pdata, 0x30, file_size); + SIVAL(pdata, 0x38, nlink); + SCVAL(pdata, 0x3C, delete_pending); + SCVAL(pdata, 0x3D, (mode&aDIR)?1:0); + SSVAL(pdata, 0x3E, 0); /* padding */ + SBVAL(pdata, 0x40, file_index); + SIVAL(pdata, 0x48, ea_size); + SIVAL(pdata, 0x4C, access_mask); + SBVAL(pdata, 0x50, pos); + SIVAL(pdata, 0x58, mode); /*TODO: mode != mode fix this!!! */ + SIVAL(pdata, 0x5C, 0); /* No alignment needed. */ + + pdata += 0x60; + + len = srvstr_push(dstart, flags2, + pdata+4, dos_fname, + PTR_DIFF(dend, pdata+4), + STR_UNICODE); + SIVAL(pdata,0,len); + pdata += 4 + len; + data_size = PTR_DIFF(pdata,(*ppdata)); + break; + } case SMB_FILE_INTERNAL_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); -- cgit From 64221bc3facde5d2e6d35516eb997d83c5f90d35 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Jul 2009 16:40:58 +0200 Subject: s3:smbd: add support for marshalling SMB2 FileFullEaInformation metze --- source3/smbd/trans2.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index f13c2f0338..6554fb67b7 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -367,6 +367,69 @@ static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned in return ret_data_size; } +static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx, + char *pdata, + unsigned int total_data_size, + unsigned int *ret_data_size, + connection_struct *conn, + struct ea_list *ea_list) +{ + uint8_t *p = (uint8_t *)pdata; + uint8_t *last_start = NULL; + + *ret_data_size = 0; + + if (!lp_ea_support(SNUM(conn))) { + return NT_STATUS_NO_EAS_ON_FILE; + } + + for (; ea_list; ea_list = ea_list->next) { + size_t dos_namelen; + fstring dos_ea_name; + size_t this_size; + + if (last_start) { + SIVAL(last_start, 0, PTR_DIFF(p, last_start)); + } + last_start = p; + + push_ascii_fstring(dos_ea_name, ea_list->ea.name); + dos_namelen = strlen(dos_ea_name); + if (dos_namelen > 255 || dos_namelen == 0) { + return NT_STATUS_INTERNAL_ERROR; + } + if (ea_list->ea.value.length > 65535) { + return NT_STATUS_INTERNAL_ERROR; + } + + this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length; + + if (ea_list->next) { + size_t pad = 4 - (this_size % 4); + this_size += pad; + } + + if (this_size > total_data_size) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + + /* We know we have room. */ + SIVAL(p, 0x00, 0); /* next offset */ + SCVAL(p, 0x04, ea_list->ea.flags); + SCVAL(p, 0x05, dos_namelen); + SSVAL(p, 0x06, ea_list->ea.value.length); + fstrcpy((char *)(p+0x08), dos_ea_name); + memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length); + + total_data_size -= this_size; + p += this_size; + } + + *ret_data_size = PTR_DIFF(p, pdata); + DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size)); + return NT_STATUS_OK; +} + static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname) { size_t total_ea_len = 0; @@ -4105,6 +4168,35 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, break; } + case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/ + { + /* We have data_size bytes to put EA's into. */ + size_t total_ea_len = 0; + struct ea_list *ea_file_list = NULL; + + DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n")); + + /*TODO: add filtering and index handling */ + + ea_file_list = get_ea_list_from_file(mem_ctx, + conn, fsp, + fname, + &total_ea_len); + if (!ea_file_list) { + return NT_STATUS_NO_EAS_ON_FILE; + } + + status = fill_ea_chained_buffer(mem_ctx, + pdata, + data_size, + &data_size, + conn, ea_file_list); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + break; + } + case SMB_FILE_BASIC_INFORMATION: case SMB_QUERY_FILE_BASIC_INFO: -- cgit From d7809f65cf25ea10b3edd7df209cbf67a43df138 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2009 20:39:08 +0200 Subject: s3:smbd: start SMB2 GetInfo support for File*Information levels TODO: the EA levels are not fully supported. metze --- source3/smbd/smb2_getinfo.c | 140 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index ba725fdec9..b6b7462e90 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -233,7 +233,145 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + if (IS_IPC(conn)) { + tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); + return tevent_req_post(req, ev); + } + + switch (in_info_type) { + case 0x01:/* SMB2_GETINFO_FILE */ + { + uint16_t file_info_level; + char *data = NULL; + unsigned int data_size = 0; + struct smb_filename *smb_fname = NULL; + bool delete_pending = false; + struct timespec write_time_ts; + struct file_id fileid; + struct ea_list *ea_list = NULL; + int lock_data_count = 0; + char *lock_data = NULL; + bool ms_dfs_link = false; + NTSTATUS status; + + ZERO_STRUCT(write_time_ts); + + switch (in_file_info_class) { + case 0x0F:/* RAW_FILEINFO_SMB2_ALL_EAS */ + file_info_level = 0xFF00 | in_file_info_class; + break; + + case 0x12:/* RAW_FILEINFO_SMB2_ALL_INFORMATION */ + file_info_level = 0xFF00 | in_file_info_class; + break; + + default: + /* the levels directly map to the passthru levels */ + file_info_level = in_file_info_class + 1000; + break; + } + + status = create_synthetic_smb_fname_split(state, + fsp->fsp_name, + NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + if (fsp->fake_file_handle) { + /* + * This is actually for the QUOTA_FAKE_FILE --metze + */ + + /* We know this name is ok, it's already passed the checks. */ + + } else if (fsp && (fsp->is_directory || fsp->fh->fd == -1)) { + /* + * This is actually a QFILEINFO on a directory + * handle (returned from an NT SMB). NT5.0 seems + * to do this call. JRA. + */ + + if (INFO_LEVEL_IS_UNIX(file_info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname)) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_LSTAT of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + } else if (SMB_VFS_STAT(conn, smb_fname)) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_STAT of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, &delete_pending, &write_time_ts); + } else { + /* + * Original code - this is an open file. + */ + + if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + DEBUG(3, ("fstat of fnum %d failed (%s)\n", + fsp->fnum, strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, &delete_pending, &write_time_ts); + } + + status = smbd_do_qfilepathinfo(conn, state, + file_info_level, + fsp, + smb_fname, + delete_pending, + write_time_ts, + ms_dfs_link, + ea_list, + lock_data_count, + lock_data, + STR_UNICODE, + in_output_buffer_length, + &data, + &data_size); + if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(data); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + if (data_size > 0) { + state->out_output_buffer = data_blob_talloc(state, + data, + data_size); + SAFE_FREE(data); + if (tevent_req_nomem(state->out_output_buffer.data, req)) { + return tevent_req_post(req, ev); + } + } + SAFE_FREE(data); + break; + } + + default: + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + tevent_req_done(req); return tevent_req_post(req, ev); } -- cgit From f26a2ca8e43884a62bf5822e7571692870ecc7a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 08:59:32 +0200 Subject: s3:smbd: split out smbd_do_setfilepathinfo() from call_trans2setfilepathinfo() metze --- source3/smbd/trans2.c | 404 +++++++++++++++++++++++++++----------------------- 1 file changed, 216 insertions(+), 188 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 6554fb67b7..54d873065c 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7055,200 +7055,45 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, return close_file(req, fsp, NORMAL_CLOSE); } -/**************************************************************************** - Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname). -****************************************************************************/ - -static void call_trans2setfilepathinfo(connection_struct *conn, - struct smb_request *req, - unsigned int tran_call, - char **pparams, int total_params, - char **ppdata, int total_data, - unsigned int max_data_bytes) +static NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, + struct smb_request *req, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + struct smb_filename *smb_fname, + char **ppdata, int total_data, + int *ret_data_size) { - char *params = *pparams; char *pdata = *ppdata; - uint16 info_level; SMB_STRUCT_STAT sbuf; char *fname = NULL; - struct smb_filename *smb_fname = NULL; - files_struct *fsp = NULL; NTSTATUS status = NT_STATUS_OK; int data_return_size = 0; - TALLOC_CTX *ctx = talloc_tos(); - - if (!params) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - - if (tran_call == TRANSACT2_SETFILEINFO) { - if (total_params < 4) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - - fsp = file_fsp(req, SVAL(params,0)); - /* Basic check for non-null fsp. */ - if (!check_fsp_open(conn, req, fsp)) { - return; - } - info_level = SVAL(params,2); - - fname = talloc_strdup(talloc_tos(),fsp->fsp_name); - if (!fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; - } - if(fsp->is_directory || fsp->fh->fd == -1) { - /* - * This is actually a SETFILEINFO on a directory - * handle (returned from an NT SMB). NT5.0 seems - * to do this call. JRA. - */ - if (INFO_LEVEL_IS_UNIX(info_level)) { - /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { - DEBUG(3,("call_trans2setfilepathinfo: " - "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } - } else { - if (SMB_VFS_STAT(conn, smb_fname) != 0) { - DEBUG(3,("call_trans2setfilepathinfo: " - "fileinfo of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } - } - } else if (fsp->print_file) { - /* - * Doing a DELETE_ON_CLOSE should cancel a print job. - */ - if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) { - fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; - - DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name )); - - SSVAL(params,0,0); - send_trans2_replies(conn, req, params, 2, - *ppdata, 0, - max_data_bytes); - return; - } else { - reply_doserror(req, ERRDOS, ERRbadpath); - return; - } - } else { - /* - * Original code - this is an open file. - */ - if (!check_fsp(conn, req, fsp)) { - return; - } - - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { - DEBUG(3,("call_trans2setfilepathinfo: fstat " - "of fnum %d failed (%s)\n", fsp->fnum, - strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } - } - } else { - /* set path info */ - if (total_params < 7) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - - info_level = SVAL(params,0); - srvstr_get_path(ctx, params, req->flags2, &fname, ¶ms[6], - total_params - 6, STR_TERMINATE, - &status); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; - } - - status = filename_convert(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - fname, - &smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, - NT_STATUS_PATH_NOT_COVERED, - ERRSRV, ERRbadpath); - return; - } - reply_nterror(req, status); - return; - } - - if (INFO_LEVEL_IS_UNIX(info_level)) { - /* - * For CIFS UNIX extensions the target name may not exist. - */ - - /* Always do lstat for UNIX calls. */ - SMB_VFS_LSTAT(conn, smb_fname); - - } else if (!VALID_STAT(smb_fname->st) && - SMB_VFS_STAT(conn, smb_fname)) { - DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of " - "%s failed (%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } - } + *ret_data_size = 0; /* Set sbuf for use below. */ sbuf = smb_fname->st; if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } if (!CAN_WRITE(conn)) { /* Allow POSIX opens. The open path will deny * any non-readonly opens. */ if (info_level != SMB_POSIX_PATH_OPEN) { - reply_doserror(req, ERRSRV, ERRaccess); - return; + return NT_STATUS_DOS(ERRSRV, ERRaccess); } } - DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n", - tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data)); - - /* Realloc the parameter size */ - *pparams = (char *)SMB_REALLOC(*pparams,2); - if (*pparams == NULL) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + status = get_full_smb_filename(mem_ctx, smb_fname, &fname); + if (!NT_STATUS_IS_OK(status)) { + return status; } - params = *pparams; - SSVAL(params,0,0); + DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d totdata=%d\n", + fname, fsp ? fsp->fnum : -1, info_level, total_data)); switch (info_level) { @@ -7374,10 +7219,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, case SMB_SET_FILE_UNIX_LINK: { - if (tran_call != TRANSACT2_SETPATHINFO) { + if (fsp) { /* We must have a pathname for this. */ - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } status = smb_set_file_unix_link(conn, req, pdata, total_data, fname); @@ -7386,10 +7230,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, case SMB_SET_FILE_UNIX_HLINK: { - if (tran_call != TRANSACT2_SETPATHINFO || smb_fname == NULL) { + if (fsp || smb_fname == NULL) { /* We must have a pathname for this. */ - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } status = smb_set_file_unix_hlink(conn, req, pdata, total_data, @@ -7420,9 +7263,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn, case SMB_SET_POSIX_LOCK: { - if (tran_call != TRANSACT2_SETFILEINFO) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + if (fsp) { + return NT_STATUS_INVALID_LEVEL; } status = smb_set_posix_lock(conn, req, pdata, total_data, fsp); @@ -7431,10 +7273,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, case SMB_POSIX_PATH_OPEN: { - if (tran_call != TRANSACT2_SETPATHINFO) { + if (fsp) { /* We must have a pathname for this. */ - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } status = smb_posix_open(conn, req, @@ -7448,10 +7289,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, case SMB_POSIX_PATH_UNLINK: { - if (tran_call != TRANSACT2_SETPATHINFO) { + if (fsp) { /* We must have a pathname for this. */ - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } status = smb_posix_unlink(conn, req, @@ -7462,10 +7302,199 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } default: - reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return NT_STATUS_INVALID_LEVEL; + } + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + *ret_data_size = data_return_size; + return NT_STATUS_OK; +} + +/**************************************************************************** + Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname). +****************************************************************************/ + +static void call_trans2setfilepathinfo(connection_struct *conn, + struct smb_request *req, + unsigned int tran_call, + char **pparams, int total_params, + char **ppdata, int total_data, + unsigned int max_data_bytes) +{ + char *params = *pparams; + char *pdata = *ppdata; + uint16 info_level; + char *fname = NULL; + struct smb_filename *smb_fname = NULL; + files_struct *fsp = NULL; + NTSTATUS status = NT_STATUS_OK; + int data_return_size = 0; + + if (!params) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + if (tran_call == TRANSACT2_SETFILEINFO) { + if (total_params < 4) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + fsp = file_fsp(req, SVAL(params,0)); + /* Basic check for non-null fsp. */ + if (!check_fsp_open(conn, req, fsp)) { + return; + } + info_level = SVAL(params,2); + + fname = talloc_strdup(talloc_tos(),fsp->fsp_name); + if (!fname) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + + status = create_synthetic_smb_fname_split(talloc_tos(), fname, + NULL, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } + + if(fsp->is_directory || fsp->fh->fd == -1) { + /* + * This is actually a SETFILEINFO on a directory + * handle (returned from an NT SMB). NT5.0 seems + * to do this call. JRA. + */ + if (INFO_LEVEL_IS_UNIX(info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname)) { + DEBUG(3,("call_trans2setfilepathinfo: " + "SMB_VFS_LSTAT of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, map_nt_error_from_unix(errno)); + return; + } + } else { + if (SMB_VFS_STAT(conn, smb_fname) != 0) { + DEBUG(3,("call_trans2setfilepathinfo: " + "fileinfo of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, map_nt_error_from_unix(errno)); + return; + } + } + } else if (fsp->print_file) { + /* + * Doing a DELETE_ON_CLOSE should cancel a print job. + */ + if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) { + fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; + + DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name )); + + SSVAL(params,0,0); + send_trans2_replies(conn, req, params, 2, + *ppdata, 0, + max_data_bytes); + return; + } else { + reply_doserror(req, ERRDOS, ERRbadpath); + return; + } + } else { + /* + * Original code - this is an open file. + */ + if (!check_fsp(conn, req, fsp)) { + return; + } + + if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + DEBUG(3,("call_trans2setfilepathinfo: fstat " + "of fnum %d failed (%s)\n", fsp->fnum, + strerror(errno))); + reply_nterror(req, map_nt_error_from_unix(errno)); + return; + } + } + } else { + /* set path info */ + if (total_params < 7) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; + } + + info_level = SVAL(params,0); + srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6], + total_params - 6, STR_TERMINATE, + &status); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } + + status = filename_convert(req, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + &smb_fname, + &fname); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + return; + } + reply_nterror(req, status); + return; + } + + if (INFO_LEVEL_IS_UNIX(info_level)) { + /* + * For CIFS UNIX extensions the target name may not exist. + */ + + /* Always do lstat for UNIX calls. */ + SMB_VFS_LSTAT(conn, smb_fname); + + } else if (!VALID_STAT(smb_fname->st) && + SMB_VFS_STAT(conn, smb_fname)) { + DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of " + "%s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, map_nt_error_from_unix(errno)); + return; + } } + DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n", + tran_call, fname, fsp ? fsp->fnum : -1, info_level,total_data)); + + /* Realloc the parameter size */ + *pparams = (char *)SMB_REALLOC(*pparams,2); + if (*pparams == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + params = *pparams; + + SSVAL(params,0,0); + + status = smbd_do_setfilepathinfo(conn, req, req, + info_level, + fsp, + smb_fname, + ppdata, total_data, + &data_return_size); if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { /* We have re-scheduled this call. */ @@ -7489,7 +7518,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn, return; } - SSVAL(params,0,0); send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size, max_data_bytes); -- cgit From 7d735519d7f6a726240dff8cdcae36acd73df48c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 09:01:56 +0200 Subject: s3:smbd: make smbd_do_setfilepathinfo() non static for use in SMB2 SetInfo metze --- source3/smbd/globals.h | 9 +++++++++ source3/smbd/trans2.c | 16 ++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 725a94a90b..109c29a1ae 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -201,6 +201,15 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, char **ppdata, unsigned int *pdata_size); +NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, + struct smb_request *req, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + struct smb_filename *smb_fname, + char **ppdata, int total_data, + int *ret_data_size); + void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn, const char *reason, const char *location); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 54d873065c..085a0b2acb 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7055,14 +7055,14 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, return close_file(req, fsp, NORMAL_CLOSE); } -static NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, - struct smb_request *req, - TALLOC_CTX *mem_ctx, - uint16_t info_level, - files_struct *fsp, - struct smb_filename *smb_fname, - char **ppdata, int total_data, - int *ret_data_size) +NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, + struct smb_request *req, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + struct smb_filename *smb_fname, + char **ppdata, int total_data, + int *ret_data_size) { char *pdata = *ppdata; SMB_STRUCT_STAT sbuf; -- cgit From 2a92139a1ca8b2c1950f6ca32255b8fcfdeefff6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 11:54:20 +0200 Subject: s3:smbd: split out smbd_do_qfsinfo() from call_trans2qfsinfo() metze --- source3/smbd/trans2.c | 172 +++++++++++++++++++++++++++----------------------- 1 file changed, 93 insertions(+), 79 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 085a0b2acb..2ee3938aec 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2687,67 +2687,37 @@ static void samba_extended_info_version(struct smb_extended_info *extended_info) "%s", samba_version_string()); } -/**************************************************************************** - Reply to a TRANS2_QFSINFO (query filesystem info). -****************************************************************************/ - -static void call_trans2qfsinfo(connection_struct *conn, - struct smb_request *req, - char **pparams, int total_params, - char **ppdata, int total_data, - unsigned int max_data_bytes) +static NTSTATUS smbd_do_qfsinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + SMB_STRUCT_STAT st, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + int *ret_data_len) { char *pdata, *end_data; - char *params = *pparams; - uint16 info_level; - int data_len, len; - SMB_STRUCT_STAT st; + int data_len = 0, len; const char *vname = volume_label(SNUM(conn)); int snum = SNUM(conn); char *fstype = lp_fstype(SNUM(conn)); uint32 additional_flags = 0; - if (total_params < 2) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - - info_level = SVAL(params,0); - if (IS_IPC(conn)) { if (info_level != SMB_QUERY_CIFS_UNIX_INFO) { - DEBUG(0,("call_trans2qfsinfo: not an allowed " + DEBUG(0,("smbd_do_qfsinfo: not an allowed " "info level (0x%x) on IPC$.\n", (unsigned int)info_level)); - reply_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - } - - if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) { - if (info_level != SMB_QUERY_CIFS_UNIX_INFO) { - DEBUG(0,("call_trans2qfsinfo: encryption required " - "and info level 0x%x sent.\n", - (unsigned int)info_level)); - exit_server_cleanly("encryption required " - "on connection"); - return; + return NT_STATUS_ACCESS_DENIED; } } - DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); - - if(vfs_stat_smb_fname(conn,".",&st)!=0) { - DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); - reply_doserror(req, ERRSRV, ERRinvdevice); - return; - } + DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level)); *ppdata = (char *)SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); - if (*ppdata == NULL ) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + if (*ppdata == NULL) { + return NT_STATUS_NO_MEMORY; } pdata = *ppdata; @@ -2760,8 +2730,7 @@ static void call_trans2qfsinfo(connection_struct *conn, uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 18; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_nterror(req, map_nt_error_from_unix(errno)); - return; + return map_nt_error_from_unix(errno); } block_size = lp_block_size(snum); @@ -2780,7 +2749,7 @@ static void call_trans2qfsinfo(connection_struct *conn, bytes_per_sector = 512; sectors_per_unit = bsize/bytes_per_sector; - DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \ + DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit, (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); @@ -2806,13 +2775,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u * the pushed string. The change here was adding the STR_TERMINATE. JRA. */ len = srvstr_push( - pdata, req->flags2, + pdata, flags2, pdata+l2_vol_szVolLabel, vname, PTR_DIFF(end_data, pdata+l2_vol_szVolLabel), STR_NOALIGN|STR_TERMINATE); SCVAL(pdata,l2_vol_cch,len); data_len = l2_vol_szVolLabel + len; - DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n", + DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n", (unsigned)convert_timespec_to_time_t(st.st_ex_ctime), len, vname)); break; @@ -2839,7 +2808,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u SIVAL(pdata,4,255); /* Max filename component length */ /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it and will think we can't do long filenames */ - len = srvstr_push(pdata, req->flags2, pdata+12, fstype, + len = srvstr_push(pdata, flags2, pdata+12, fstype, PTR_DIFF(end_data, pdata+12), STR_UNICODE); SIVAL(pdata,8,len); @@ -2848,7 +2817,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u case SMB_QUERY_FS_LABEL_INFO: case SMB_FS_LABEL_INFORMATION: - len = srvstr_push(pdata, req->flags2, pdata+4, vname, + len = srvstr_push(pdata, flags2, pdata+4, vname, PTR_DIFF(end_data, pdata+4), 0); data_len = 4 + len; SIVAL(pdata,0,len); @@ -2865,13 +2834,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u (str_checksum(get_local_machine_name())<<16)); /* Max label len is 32 characters. */ - len = srvstr_push(pdata, req->flags2, pdata+18, vname, + len = srvstr_push(pdata, flags2, pdata+18, vname, PTR_DIFF(end_data, pdata+18), STR_UNICODE); SIVAL(pdata,12,len); data_len = 18+len; - DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", + DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", (int)strlen(vname),vname, lp_servicename(snum))); break; @@ -2881,8 +2850,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 24; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_nterror(req, map_nt_error_from_unix(errno)); - return; + return map_nt_error_from_unix(errno); } block_size = lp_block_size(snum); if (bsize < block_size) { @@ -2899,7 +2867,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u } bytes_per_sector = 512; sectors_per_unit = bsize/bytes_per_sector; - DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \ + DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit, (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); SBIG_UINT(pdata,0,dsize); @@ -2914,8 +2882,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 32; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_nterror(req, map_nt_error_from_unix(errno)); - return; + return map_nt_error_from_unix(errno); } block_size = lp_block_size(snum); if (bsize < block_size) { @@ -2932,7 +2899,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned } bytes_per_sector = 512; sectors_per_unit = bsize/bytes_per_sector; - DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \ + DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit, (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */ @@ -2990,19 +2957,18 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned "service [%s] user [%s]\n", lp_servicename(SNUM(conn)), conn->server_info->unix_name)); - reply_doserror(req, ERRDOS, ERRnoaccess); - return; + return NT_STATUS_DOS(ERRDOS, ERRnoaccess); } if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); - reply_doserror(req, ERRSRV, ERRerror); - return; + return NT_STATUS_DOS(ERRSRV, ERRerror); } data_len = 48; - DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn)))); + DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n", + lp_servicename(SNUM(conn)))); /* Unknown1 24 NULL bytes*/ SBIG_UINT(pdata,0,(uint64_t)0); @@ -3053,8 +3019,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int encrypt_caps = 0; if (!lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } switch (conn->encrypt_level) { @@ -3099,8 +3064,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned vfs_statvfs_struct svfs; if (!lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } rc = SMB_VFS_STATVFS(conn, ".", &svfs); @@ -3115,16 +3079,14 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned SBIG_UINT(pdata,32,svfs.TotalFileNodes); SBIG_UINT(pdata,40,svfs.FreeFileNodes); SBIG_UINT(pdata,48,svfs.FsIdentifier); - DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n")); + DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n")); #ifdef EOPNOTSUPP } else if (rc == EOPNOTSUPP) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; #endif /* EOPNOTSUPP */ } else { DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn)))); - reply_doserror(req, ERRSRV, ERRerror); - return; + return NT_STATUS_DOS(ERRSRV, ERRerror); } break; } @@ -3136,13 +3098,11 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int i; if (!lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } if (max_data_bytes < 40) { - reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); - return; + return NT_STATUS_BUFFER_TOO_SMALL; } /* We ARE guest if global_sid_Builtin_Guests is @@ -3256,12 +3216,66 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned } /* drop through */ default: - reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return NT_STATUS_INVALID_LEVEL; + } + + *ret_data_len = data_len; + return NT_STATUS_OK; +} + +/**************************************************************************** + Reply to a TRANS2_QFSINFO (query filesystem info). +****************************************************************************/ + +static void call_trans2qfsinfo(connection_struct *conn, + struct smb_request *req, + char **pparams, int total_params, + char **ppdata, int total_data, + unsigned int max_data_bytes) +{ + char *params = *pparams; + uint16_t info_level; + int data_len = 0; + SMB_STRUCT_STAT st; + NTSTATUS status; + + if (total_params < 2) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + info_level = SVAL(params,0); + + if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) { + if (info_level != SMB_QUERY_CIFS_UNIX_INFO) { + DEBUG(0,("call_trans2qfsinfo: encryption required " + "and info level 0x%x sent.\n", + (unsigned int)info_level)); + exit_server_cleanly("encryption required " + "on connection"); return; + } } + DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); + + if(vfs_stat_smb_fname(conn,".",&st)!=0) { + DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); + reply_doserror(req, ERRSRV, ERRinvdevice); + return; + } + + status = smbd_do_qfsinfo(conn, req, + info_level, st, + req->flags2, + max_data_bytes, + ppdata, &data_len); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } - send_trans2_replies(conn, req, params, 0, pdata, data_len, + send_trans2_replies(conn, req, params, 0, *ppdata, data_len, max_data_bytes); DEBUG( 4, ( "%s info_level = %d\n", -- cgit From ed99bf7317fccdb13e832e98f389486443f9fd48 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 12:05:34 +0200 Subject: s3:smbd: make smbd_do_qfsinfo() non static for use in SMB2 GetInfo metze --- source3/smbd/globals.h | 9 +++++++++ source3/smbd/trans2.c | 16 ++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 109c29a1ae..cd3e054d1a 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -210,6 +210,15 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, char **ppdata, int total_data, int *ret_data_size); +NTSTATUS smbd_do_qfsinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + SMB_STRUCT_STAT st, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + int *ret_data_len); + void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn, const char *reason, const char *location); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 2ee3938aec..4dd0375067 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2687,14 +2687,14 @@ static void samba_extended_info_version(struct smb_extended_info *extended_info) "%s", samba_version_string()); } -static NTSTATUS smbd_do_qfsinfo(connection_struct *conn, - TALLOC_CTX *mem_ctx, - uint16_t info_level, - SMB_STRUCT_STAT st, - uint16_t flags2, - unsigned int max_data_bytes, - char **ppdata, - int *ret_data_len) +NTSTATUS smbd_do_qfsinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + SMB_STRUCT_STAT st, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + int *ret_data_len) { char *pdata, *end_data; int data_len = 0, len; -- cgit From 3ee3eb3acf5783894f358c415b342a88db248449 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 13:14:39 +0200 Subject: s3:smbd: close_file() handles named pipes just fine, no reason to return NOT_SUPPORTED metze --- source3/smbd/smb2_close.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index 6724e5cc15..a46b36e2bb 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -107,11 +107,6 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, return NT_STATUS_NO_MEMORY; } - /* If it's an IPC, pass off the pipe handler. */ - if (IS_IPC(conn)) { - return NT_STATUS_NOT_IMPLEMENTED; - } - fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile); if (fsp == NULL) { return NT_STATUS_FILE_CLOSED; -- cgit From 8db45607f8d19781d33ebff0d0b13c473f34009b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 12 Jun 2009 14:27:19 +0200 Subject: libds: share UF_ flags between samba3 and 4. Guenther --- libds/common/flags.h | 177 ++++++++++++++++++++++++ source3/include/ads.h | 127 +---------------- source4/dsdb/common/flag_mapping.c | 2 +- source4/dsdb/common/flags.h | 137 ------------------ source4/dsdb/common/sidmap.c | 2 +- source4/dsdb/common/util.c | 2 +- source4/dsdb/samdb/ldb_modules/instancetype.c | 2 +- source4/dsdb/samdb/ldb_modules/password_hash.c | 2 +- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 2 +- source4/dsdb/samdb/samdb.c | 2 +- source4/dsdb/samdb/samdb.h | 2 +- source4/kdc/hdb-samba4.c | 2 +- source4/kdc/pac-glue.c | 2 +- source4/libnet/libnet_become_dc.c | 2 +- source4/libnet/libnet_unbecome_dc.c | 2 +- source4/rpc_server/netlogon/dcerpc_netlogon.c | 2 +- source4/rpc_server/samr/dcesrv_samr.c | 2 +- source4/rpc_server/samr/samr_password.c | 2 +- 18 files changed, 194 insertions(+), 277 deletions(-) create mode 100644 libds/common/flags.h delete mode 100644 source4/dsdb/common/flags.h diff --git a/libds/common/flags.h b/libds/common/flags.h new file mode 100644 index 0000000000..2b342af8d6 --- /dev/null +++ b/libds/common/flags.h @@ -0,0 +1,177 @@ +/* + Unix SMB/CIFS implementation. + User/Group specific flags + + Copyright (C) Andrew Tridgell 2001-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 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 . +*/ + +/* UserFlags for userAccountControl */ +#define UF_SCRIPT 0x00000001 /* NT or Lan Manager Login script must be executed */ +#define UF_ACCOUNTDISABLE 0x00000002 +#define UF_00000004 0x00000004 +#define UF_HOMEDIR_REQUIRED 0x00000008 + +#define UF_LOCKOUT 0x00000010 +#define UF_PASSWD_NOTREQD 0x00000020 +#define UF_PASSWD_CANT_CHANGE 0x00000040 +#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080 + +#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 /* Local user account in usrmgr */ +#define UF_NORMAL_ACCOUNT 0x00000200 +#define UF_00000400 0x00000400 +#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800 + +#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000 +#define UF_SERVER_TRUST_ACCOUNT 0x00002000 +#define UF_00004000 0x00004000 +#define UF_00008000 0x00008000 + +#define UF_DONT_EXPIRE_PASSWD 0x00010000 +#define UF_MNS_LOGON_ACCOUNT 0x00020000 +#define UF_SMARTCARD_REQUIRED 0x00040000 +#define UF_TRUSTED_FOR_DELEGATION 0x00080000 + +#define UF_NOT_DELEGATED 0x00100000 +#define UF_USE_DES_KEY_ONLY 0x00200000 +#define UF_DONT_REQUIRE_PREAUTH 0x00400000 +#define UF_PASSWORD_EXPIRED 0x00800000 + +#define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000 +#define UF_NO_AUTH_DATA_REQUIRED 0x02000000 + +#define UF_MACHINE_ACCOUNT_MASK (\ + UF_INTERDOMAIN_TRUST_ACCOUNT |\ + UF_WORKSTATION_TRUST_ACCOUNT |\ + UF_SERVER_TRUST_ACCOUNT \ + ) + +#define UF_ACCOUNT_TYPE_MASK (\ + UF_TEMP_DUPLICATE_ACCOUNT |\ + UF_NORMAL_ACCOUNT |\ + UF_INTERDOMAIN_TRUST_ACCOUNT |\ + UF_WORKSTATION_TRUST_ACCOUNT |\ + UF_SERVER_TRUST_ACCOUNT \ + ) + +#define UF_SETTABLE_BITS (\ + UF_SCRIPT |\ + UF_ACCOUNTDISABLE |\ + UF_HOMEDIR_REQUIRED |\ + UF_LOCKOUT |\ + UF_PASSWD_NOTREQD |\ + UF_PASSWD_CANT_CHANGE |\ + UF_ACCOUNT_TYPE_MASK | \ + UF_DONT_EXPIRE_PASSWD | \ + UF_MNS_LOGON_ACCOUNT |\ + UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\ + UF_SMARTCARD_REQUIRED |\ + UF_TRUSTED_FOR_DELEGATION |\ + UF_NOT_DELEGATED |\ + UF_USE_DES_KEY_ONLY |\ + UF_DONT_REQUIRE_PREAUTH \ + ) + +/* sAMAccountType */ +#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */ +#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */ +#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */ +#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */ +#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */ +#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP +#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */ +#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */ + +#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */ +#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */ +#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */ + +/* groupType */ +#define GROUP_TYPE_BUILTIN_LOCAL_GROUP 0x00000001 +#define GROUP_TYPE_ACCOUNT_GROUP 0x00000002 +#define GROUP_TYPE_RESOURCE_GROUP 0x00000004 +#define GROUP_TYPE_UNIVERSAL_GROUP 0x00000008 +#define GROUP_TYPE_APP_BASIC_GROUP 0x00000010 +#define GROUP_TYPE_APP_QUERY_GROUP 0x00000020 +#define GROUP_TYPE_SECURITY_ENABLED 0x80000000 + +#define GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ( \ + /* 0x80000005 -2147483643 */ \ + GROUP_TYPE_BUILTIN_LOCAL_GROUP| \ + GROUP_TYPE_RESOURCE_GROUP| \ + GROUP_TYPE_SECURITY_ENABLED \ + ) +#define GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ( \ + /* 0x80000004 -2147483644 */ \ + GROUP_TYPE_RESOURCE_GROUP| \ + GROUP_TYPE_SECURITY_ENABLED \ + ) +#define GTYPE_SECURITY_GLOBAL_GROUP ( \ + /* 0x80000002 -2147483646 */ \ + GROUP_TYPE_ACCOUNT_GROUP| \ + GROUP_TYPE_SECURITY_ENABLED \ + ) +#define GTYPE_SECURITY_UNIVERSAL_GROUP ( \ + /* 0x80000008 -2147483656 */ \ + GROUP_TYPE_UNIVERSAL_GROUP| \ + GROUP_TYPE_SECURITY_ENABLED \ + ) +#define GTYPE_DISTRIBUTION_GLOBAL_GROUP 0x00000002 /* 2 */ +#define GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP 0x00000004 /* 4 */ +#define GTYPE_DISTRIBUTION_UNIVERSAL_GROUP 0x00000008 /* 8 */ + +#define INSTANCE_TYPE_IS_NC_HEAD 0x00000001 +#define INSTANCE_TYPE_UNINSTANT 0x00000002 +#define INSTANCE_TYPE_WRITE 0x00000004 +#define INSTANCE_TYPE_NC_ABOVE 0x00000008 +#define INSTANCE_TYPE_NC_COMING 0x00000010 +#define INSTANCE_TYPE_NC_GOING 0x00000020 + +#define SYSTEM_FLAG_CR_NTDS_NC 0x00000001 +#define SYSTEM_FLAG_CR_NTDS_DOMAIN 0x00000002 +#define SYSTEM_FLAG_CR_NTDS_NOT_GC_REPLICATED 0x00000004 +#define SYSTEM_FLAG_SCHEMA_BASE_OBJECT 0x00000010 +#define SYSTEM_FLAG_ATTR_IS_RDN 0x00000020 +#define SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE 0x02000000 +#define SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE 0x04000000 +#define SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME 0x08000000 +#define SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE 0x10000000 +#define SYSTEM_FLAG_CONFIG_ALLOW_MOVE 0x20000000 +#define SYSTEM_FLAG_CONFIG_ALLOW_RENAME 0x40000000 +#define SYSTEM_FLAG_DISALLOW_DELTE 0x80000000 + +#define SEARCH_FLAG_ATTINDEX 0x0000001 +#define SEARCH_FLAG_PDNTATTINDEX 0x0000002 +#define SEARCH_FLAG_ANR 0x0000004 +#define SEARCH_FLAG_PRESERVEONDELETE 0x0000008 +#define SEARCH_FLAG_COPY 0x0000010 +#define SEARCH_FLAG_TUPLEINDEX 0x0000020 +#define SEARCH_FLAG_SUBTREEATTRINDEX 0x0000040 +#define SEARCH_FLAG_CONFIDENTIAL 0x0000080 +#define SEARCH_FLAG_NEVERVALUEAUDIT 0x0000100 +#define SEARCH_FLAG_RODC_ATTRIBUTE 0x0000200 + +#define DS_BEHAVIOR_WIN2000 0 +#define DS_BEHAVIOR_WIN2003_INTERIM 1 +#define DS_BEHAVIOR_WIN2003 2 +#define DS_BEHAVIOR_WIN2008 3 + +/* Settings for the domainFunctionality attribute in the rootDSE */ + +#define DS_DOMAIN_FUNCTION_2000 0 +#define DS_DOMAIN_FUCNTION_2003_MIXED 1 +#define DS_DOMAIN_FUNCTION_2003 2 +#define DS_DOMAIN_FUNCTION_2008 3 + diff --git a/source3/include/ads.h b/source3/include/ads.h index afa4e12175..9761d54086 100644 --- a/source3/include/ads.h +++ b/source3/include/ads.h @@ -6,6 +6,8 @@ basically this is a wrapper around ldap */ +#include "../libds/common/flags.h" + enum wb_posix_mapping { WB_POSIX_MAP_UNKNOWN = -1, WB_POSIX_MAP_TEMPLATE = 0, @@ -202,124 +204,6 @@ typedef void **ADS_MODLIST; #define ADS_LDAP_MATCHING_RULE_BIT_AND "1.2.840.113556.1.4.803" #define ADS_LDAP_MATCHING_RULE_BIT_OR "1.2.840.113556.1.4.804" -/* UserFlags for userAccountControl */ -#define UF_SCRIPT 0x00000001 -#define UF_ACCOUNTDISABLE 0x00000002 -#define UF_UNUSED_1 0x00000004 -#define UF_HOMEDIR_REQUIRED 0x00000008 - -#define UF_LOCKOUT 0x00000010 -#define UF_PASSWD_NOTREQD 0x00000020 -#define UF_PASSWD_CANT_CHANGE 0x00000040 -#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080 - -#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 -#define UF_NORMAL_ACCOUNT 0x00000200 -#define UF_UNUSED_2 0x00000400 -#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800 - -#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000 -#define UF_SERVER_TRUST_ACCOUNT 0x00002000 -#define UF_UNUSED_3 0x00004000 -#define UF_UNUSED_4 0x00008000 - -#define UF_DONT_EXPIRE_PASSWD 0x00010000 -#define UF_MNS_LOGON_ACCOUNT 0x00020000 -#define UF_SMARTCARD_REQUIRED 0x00040000 -#define UF_TRUSTED_FOR_DELEGATION 0x00080000 - -#define UF_NOT_DELEGATED 0x00100000 -#define UF_USE_DES_KEY_ONLY 0x00200000 -#define UF_DONT_REQUIRE_PREAUTH 0x00400000 -#define UF_PASSWORD_EXPIRED 0x00800000 - -#define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000 -#define UF_NO_AUTH_DATA_REQUIRED 0x02000000 -#define UF_UNUSED_8 0x04000000 -#define UF_UNUSED_9 0x08000000 - -#define UF_UNUSED_10 0x10000000 -#define UF_UNUSED_11 0x20000000 -#define UF_UNUSED_12 0x40000000 -#define UF_UNUSED_13 0x80000000 - -#define UF_MACHINE_ACCOUNT_MASK (\ - UF_INTERDOMAIN_TRUST_ACCOUNT |\ - UF_WORKSTATION_TRUST_ACCOUNT |\ - UF_SERVER_TRUST_ACCOUNT \ - ) - -#define UF_ACCOUNT_TYPE_MASK (\ - UF_TEMP_DUPLICATE_ACCOUNT |\ - UF_NORMAL_ACCOUNT |\ - UF_INTERDOMAIN_TRUST_ACCOUNT |\ - UF_WORKSTATION_TRUST_ACCOUNT |\ - UF_SERVER_TRUST_ACCOUNT \ - ) - -#define UF_SETTABLE_BITS (\ - UF_SCRIPT |\ - UF_ACCOUNTDISABLE |\ - UF_HOMEDIR_REQUIRED |\ - UF_LOCKOUT |\ - UF_PASSWD_NOTREQD |\ - UF_PASSWD_CANT_CHANGE |\ - UF_ACCOUNT_TYPE_MASK | \ - UF_DONT_EXPIRE_PASSWD | \ - UF_MNS_LOGON_ACCOUNT |\ - UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\ - UF_SMARTCARD_REQUIRED |\ - UF_TRUSTED_FOR_DELEGATION |\ - UF_NOT_DELEGATED |\ - UF_USE_DES_KEY_ONLY |\ - UF_DONT_REQUIRE_PREAUTH \ - ) - -/* sAMAccountType */ -#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */ -#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */ -#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */ -#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */ -#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */ -#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP -#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */ -#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */ - -#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */ -#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */ -#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */ - -/* groupType */ -#define GROUP_TYPE_BUILTIN_LOCAL_GROUP 0x00000001 -#define GROUP_TYPE_ACCOUNT_GROUP 0x00000002 -#define GROUP_TYPE_RESOURCE_GROUP 0x00000004 -#define GROUP_TYPE_UNIVERSAL_GROUP 0x00000008 -#define GROUP_TYPE_APP_BASIC_GROUP 0x00000010 -#define GROUP_TYPE_APP_QUERY_GROUP 0x00000020 -#define GROUP_TYPE_SECURITY_ENABLED 0x80000000 - -#define GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ( /* 0x80000005 -2147483643 */ \ - GROUP_TYPE_BUILTIN_LOCAL_GROUP| \ - GROUP_TYPE_RESOURCE_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) -#define GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ( /* 0x80000004 -2147483644 */ \ - GROUP_TYPE_RESOURCE_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) -#define GTYPE_SECURITY_GLOBAL_GROUP ( /* 0x80000002 -2147483646 */ \ - GROUP_TYPE_ACCOUNT_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) -#define GTYPE_SECURITY_UNIVERSAL_GROUP ( /* 0x80000008 -2147483656 */ \ - GROUP_TYPE_UNIVERSAL_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) - -#define GTYPE_DISTRIBUTION_GLOBAL_GROUP 0x00000002 /* 2 */ -#define GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP 0x00000004 /* 4 */ -#define GTYPE_DISTRIBUTION_UNIVERSAL_GROUP 0x00000008 /* 8 */ - #define ADS_PINGS 0x0000FFFF /* Ping response */ #define ADS_DNS_CONTROLLER 0x20000000 /* DomainControllerName is a DNS name*/ #define ADS_DNS_DOMAIN 0x40000000 /* DomainName is a DNS name */ @@ -411,11 +295,4 @@ typedef struct { #define ADS_IGNORE_PRINCIPAL "not_defined_in_RFC4178@please_ignore" -/* Settings for the domainFunctionality attribute in the rootDSE */ - -#define DS_DOMAIN_FUNCTION_2000 0 -#define DS_DOMAIN_FUCNTION_2003_MIXED 1 -#define DS_DOMAIN_FUNCTION_2003 2 -#define DS_DOMAIN_FUNCTION_2008 3 - #endif /* _INCLUDE_ADS_H_ */ diff --git a/source4/dsdb/common/flag_mapping.c b/source4/dsdb/common/flag_mapping.c index dceb41be67..af284c41e7 100644 --- a/source4/dsdb/common/flag_mapping.c +++ b/source4/dsdb/common/flag_mapping.c @@ -21,7 +21,7 @@ #include "includes.h" #include "librpc/gen_ndr/samr.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "lib/ldb/include/ldb.h" #include "dsdb/common/proto.h" diff --git a/source4/dsdb/common/flags.h b/source4/dsdb/common/flags.h deleted file mode 100644 index dd8081732c..0000000000 --- a/source4/dsdb/common/flags.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - Unix SMB/CIFS implementation. - User/Group specific flags - - Copyright (C) Andrew Tridgell 2001-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 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 . -*/ - -/* UserFlags for userAccountControl */ -#define UF_SCRIPT 0x00000001 /* NT or Lan Manager Login script must be executed */ -#define UF_ACCOUNTDISABLE 0x00000002 -#define UF_00000004 0x00000004 -#define UF_HOMEDIR_REQUIRED 0x00000008 - -#define UF_LOCKOUT 0x00000010 -#define UF_PASSWD_NOTREQD 0x00000020 -#define UF_PASSWD_CANT_CHANGE 0x00000040 -#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080 - -#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 /* Local user account in usrmgr */ -#define UF_NORMAL_ACCOUNT 0x00000200 -#define UF_00000400 0x00000400 -#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800 - -#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000 -#define UF_SERVER_TRUST_ACCOUNT 0x00002000 -#define UF_00004000 0x00004000 -#define UF_00008000 0x00008000 - -#define UF_DONT_EXPIRE_PASSWD 0x00010000 -#define UF_MNS_LOGON_ACCOUNT 0x00020000 -#define UF_SMARTCARD_REQUIRED 0x00040000 -#define UF_TRUSTED_FOR_DELEGATION 0x00080000 - -#define UF_NOT_DELEGATED 0x00100000 -#define UF_USE_DES_KEY_ONLY 0x00200000 -#define UF_DONT_REQUIRE_PREAUTH 0x00400000 -#define UF_PASSWORD_EXPIRED 0x00800000 - -#define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000 -#define UF_NO_AUTH_DATA_REQUIRED 0x02000000 - -/* sAMAccountType */ -#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */ -#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */ -#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */ -#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */ -#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */ -#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP -#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */ -#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */ - -#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */ -#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */ -#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */ - -/* groupType */ -#define GROUP_TYPE_BUILTIN_LOCAL_GROUP 0x00000001 -#define GROUP_TYPE_ACCOUNT_GROUP 0x00000002 -#define GROUP_TYPE_RESOURCE_GROUP 0x00000004 -#define GROUP_TYPE_UNIVERSAL_GROUP 0x00000008 -#define GROUP_TYPE_APP_BASIC_GROUP 0x00000010 -#define GROUP_TYPE_APP_QUERY_GROUP 0x00000020 -#define GROUP_TYPE_SECURITY_ENABLED 0x80000000 - -#define GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ( \ - /* 0x80000005 -2147483643 */ \ - GROUP_TYPE_BUILTIN_LOCAL_GROUP| \ - GROUP_TYPE_RESOURCE_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) -#define GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ( \ - /* 0x80000004 -2147483644 */ \ - GROUP_TYPE_RESOURCE_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) -#define GTYPE_SECURITY_GLOBAL_GROUP ( \ - /* 0x80000002 -2147483646 */ \ - GROUP_TYPE_ACCOUNT_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) -#define GTYPE_SECURITY_UNIVERSAL_GROUP ( \ - /* 0x80000008 -2147483656 */ \ - GROUP_TYPE_UNIVERSAL_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) -#define GTYPE_DISTRIBUTION_GLOBAL_GROUP 0x00000002 /* 2 */ -#define GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP 0x00000004 /* 4 */ -#define GTYPE_DISTRIBUTION_UNIVERSAL_GROUP 0x00000008 /* 8 */ - -#define INSTANCE_TYPE_IS_NC_HEAD 0x00000001 -#define INSTANCE_TYPE_UNINSTANT 0x00000002 -#define INSTANCE_TYPE_WRITE 0x00000004 -#define INSTANCE_TYPE_NC_ABOVE 0x00000008 -#define INSTANCE_TYPE_NC_COMING 0x00000010 -#define INSTANCE_TYPE_NC_GOING 0x00000020 - -#define SYSTEM_FLAG_CR_NTDS_NC 0x00000001 -#define SYSTEM_FLAG_CR_NTDS_DOMAIN 0x00000002 -#define SYSTEM_FLAG_CR_NTDS_NOT_GC_REPLICATED 0x00000004 -#define SYSTEM_FLAG_SCHEMA_BASE_OBJECT 0x00000010 -#define SYSTEM_FLAG_ATTR_IS_RDN 0x00000020 -#define SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE 0x02000000 -#define SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE 0x04000000 -#define SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME 0x08000000 -#define SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE 0x10000000 -#define SYSTEM_FLAG_CONFIG_ALLOW_MOVE 0x20000000 -#define SYSTEM_FLAG_CONFIG_ALLOW_RENAME 0x40000000 -#define SYSTEM_FLAG_DISALLOW_DELTE 0x80000000 - -#define SEARCH_FLAG_ATTINDEX 0x0000001 -#define SEARCH_FLAG_PDNTATTINDEX 0x0000002 -#define SEARCH_FLAG_ANR 0x0000004 -#define SEARCH_FLAG_PRESERVEONDELETE 0x0000008 -#define SEARCH_FLAG_COPY 0x0000010 -#define SEARCH_FLAG_TUPLEINDEX 0x0000020 -#define SEARCH_FLAG_SUBTREEATTRINDEX 0x0000040 -#define SEARCH_FLAG_CONFIDENTIAL 0x0000080 -#define SEARCH_FLAG_NEVERVALUEAUDIT 0x0000100 -#define SEARCH_FLAG_RODC_ATTRIBUTE 0x0000200 - -#define DS_BEHAVIOR_WIN2000 0 -#define DS_BEHAVIOR_WIN2003_INTERIM 1 -#define DS_BEHAVIOR_WIN2003 2 -#define DS_BEHAVIOR_WIN2008 3 diff --git a/source4/dsdb/common/sidmap.c b/source4/dsdb/common/sidmap.c index 5c20149384..a2aa717ace 100644 --- a/source4/dsdb/common/sidmap.c +++ b/source4/dsdb/common/sidmap.c @@ -21,7 +21,7 @@ #include "includes.h" #include "system/passwd.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "dsdb/samdb/samdb.h" #include "auth/auth.h" #include "libcli/ldap/ldap_ndr.h" diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index cbae2ec24c..30669ebd5a 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -31,7 +31,7 @@ #include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_misc.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "dsdb/common/proto.h" #include "libcli/ldap/ldap_ndr.h" #include "param/param.h" diff --git a/source4/dsdb/samdb/ldb_modules/instancetype.c b/source4/dsdb/samdb/ldb_modules/instancetype.c index 8d648d6d82..f0d56ac627 100644 --- a/source4/dsdb/samdb/ldb_modules/instancetype.c +++ b/source4/dsdb/samdb/ldb_modules/instancetype.c @@ -38,7 +38,7 @@ #include "ldb_module.h" #include "librpc/gen_ndr/ndr_misc.h" #include "dsdb/samdb/samdb.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" struct it_context { struct ldb_module *module; diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 44b7ef91e9..a28ca1d568 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -42,7 +42,7 @@ #include "auth/kerberos/kerberos.h" #include "system/time.h" #include "dsdb/samdb/samdb.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "dsdb/samdb/ldb_modules/password_modules.h" #include "librpc/ndr/libndr.h" #include "librpc/gen_ndr/ndr_drsblobs.h" diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 41f4e8e7d5..53d6d0749c 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -41,7 +41,7 @@ #include "includes.h" #include "ldb_module.h" #include "dsdb/samdb/samdb.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c index 851187380b..08e6e0d985 100644 --- a/source4/dsdb/samdb/samdb.c +++ b/source4/dsdb/samdb/samdb.c @@ -36,7 +36,7 @@ #include "ldb_wrap.h" #include "../lib/util/util_ldb.h" #include "dsdb/samdb/samdb.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "param/param.h" #include "lib/events/events.h" #include "auth/credentials/credentials.h" diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index 49dc14d74c..1493345b9d 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -38,7 +38,7 @@ struct tevent_context; #include "dsdb/schema/schema.h" #include "dsdb/samdb/samdb_proto.h" #include "dsdb/common/proto.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #define DSDB_CONTROL_CURRENT_PARTITION_OID "1.3.6.1.4.1.7165.4.3.2" struct dsdb_control_current_partition { diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 7d731ab13d..84050edb7c 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -34,7 +34,7 @@ #include "includes.h" #include "system/time.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" #include "librpc/gen_ndr/netlogon.h" diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c index 5bd4cb10c7..21ae7091a6 100644 --- a/source4/kdc/pac-glue.c +++ b/source4/kdc/pac-glue.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "lib/ldb/include/ldb.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "librpc/gen_ndr/krb5pac.h" diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c index dbbabd6a6d..b89e238a1c 100644 --- a/source4/libnet/libnet_become_dc.c +++ b/source4/libnet/libnet_become_dc.c @@ -25,7 +25,7 @@ #include "lib/ldb/include/ldb_errors.h" #include "lib/ldb_wrap.h" #include "dsdb/samdb/samdb.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "librpc/gen_ndr/ndr_drsuapi_c.h" #include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_misc.h" diff --git a/source4/libnet/libnet_unbecome_dc.c b/source4/libnet/libnet_unbecome_dc.c index e0e5e42115..3bd7a4e287 100644 --- a/source4/libnet/libnet_unbecome_dc.c +++ b/source4/libnet/libnet_unbecome_dc.c @@ -25,7 +25,7 @@ #include "lib/ldb/include/ldb_errors.h" #include "lib/ldb_wrap.h" #include "dsdb/samdb/samdb.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "librpc/gen_ndr/ndr_drsuapi_c.h" #include "param/param.h" diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index dc2d078d6b..4d10d961f9 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -27,7 +27,7 @@ #include "auth/auth.h" #include "auth/auth_sam_reply.h" #include "dsdb/samdb/samdb.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "rpc_server/samr/proto.h" #include "../lib/util/util_ldb.h" #include "libcli/auth/libcli_auth.h" diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 03acf97cab..489247c1d0 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -29,7 +29,7 @@ #include "system/time.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "dsdb/samdb/samdb.h" #include "libcli/ldap/ldap_ndr.h" #include "libcli/security/security.h" diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index ec83cbfdc9..6f12d2f119 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -26,7 +26,7 @@ #include "rpc_server/samr/dcesrv_samr.h" #include "system/time.h" #include "../lib/crypto/crypto.h" -#include "dsdb/common/flags.h" +#include "../libds/common/flags.h" #include "libcli/ldap/ldap.h" #include "dsdb/samdb/samdb.h" #include "auth/auth.h" -- cgit From 05fbe0c7f763fbe8c1c48eb82ebdfe04bfa034ea Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 12 Jun 2009 15:20:48 +0200 Subject: libds: merge the UF<->ACB flag mapping functions. Guenther --- libds/common/flag_mapping.c | 143 ++++++++++++++++++++++++++++++ source3/Makefile.in | 2 +- source3/include/proto.h | 16 ++-- source3/lib/ads_flags.c | 150 -------------------------------- source3/lib/netapi/user.c | 2 +- source3/passdb/pdb_ads.c | 6 +- source3/winbindd/winbindd_ads.c | 2 +- source4/cldap_server/netlogon.c | 2 +- source4/dsdb/common/flag_mapping.c | 145 ------------------------------ source4/dsdb/common/sidmap.c | 4 +- source4/dsdb/common/util.c | 4 +- source4/dsdb/config.mk | 4 +- source4/dsdb/samdb/ldb_modules/samldb.c | 8 +- source4/rpc_server/lsa/lsa_lookup.c | 4 +- source4/rpc_server/samr/dcesrv_samr.c | 6 +- 15 files changed, 174 insertions(+), 324 deletions(-) create mode 100644 libds/common/flag_mapping.c delete mode 100644 source3/lib/ads_flags.c delete mode 100644 source4/dsdb/common/flag_mapping.c diff --git a/libds/common/flag_mapping.c b/libds/common/flag_mapping.c new file mode 100644 index 0000000000..dc7d80185a --- /dev/null +++ b/libds/common/flag_mapping.c @@ -0,0 +1,143 @@ +/* + Unix SMB/CIFS implementation. + helper mapping functions for the UF and ACB flags + + Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Andrew Tridgell 2004 + + 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 "librpc/gen_ndr/samr.h" +#include "../libds/common/flags.h" + +/* +translated the ACB_CTRL Flags to UserFlags (userAccountControl) +*/ +/* mapping between ADS userAccountControl and SAMR acct_flags */ +static const struct { + uint32_t uf; + uint32_t acb; +} acct_flags_map[] = { + { UF_ACCOUNTDISABLE, ACB_DISABLED }, + { UF_HOMEDIR_REQUIRED, ACB_HOMDIRREQ }, + { UF_PASSWD_NOTREQD, ACB_PWNOTREQ }, + { UF_TEMP_DUPLICATE_ACCOUNT, ACB_TEMPDUP }, + { UF_NORMAL_ACCOUNT, ACB_NORMAL }, + { UF_MNS_LOGON_ACCOUNT, ACB_MNS }, + { UF_INTERDOMAIN_TRUST_ACCOUNT, ACB_DOMTRUST }, + { UF_WORKSTATION_TRUST_ACCOUNT, ACB_WSTRUST }, + { UF_SERVER_TRUST_ACCOUNT, ACB_SVRTRUST }, + { UF_DONT_EXPIRE_PASSWD, ACB_PWNOEXP }, + { UF_LOCKOUT, ACB_AUTOLOCK }, + { UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, ACB_ENC_TXT_PWD_ALLOWED }, + { UF_SMARTCARD_REQUIRED, ACB_SMARTCARD_REQUIRED }, + { UF_TRUSTED_FOR_DELEGATION, ACB_TRUSTED_FOR_DELEGATION }, + { UF_NOT_DELEGATED, ACB_NOT_DELEGATED }, + { UF_USE_DES_KEY_ONLY, ACB_USE_DES_KEY_ONLY}, + { UF_DONT_REQUIRE_PREAUTH, ACB_DONT_REQUIRE_PREAUTH }, + { UF_PASSWORD_EXPIRED, ACB_PW_EXPIRED }, + { UF_NO_AUTH_DATA_REQUIRED, ACB_NO_AUTH_DATA_REQD } +}; + +uint32_t ds_acb2uf(uint32_t acb) +{ + uint32_t i, ret = 0; + for (i=0;i. -*/ - -#include "includes.h" - -/* -translated the ACB_CTRL Flags to UserFlags (userAccountControl) -*/ -uint32 ads_acb2uf(uint32 acb) -{ - uint32 uf = 0x00000000; - - if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE; - if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED; - if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD; - if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT; - if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT; - if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT; - if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT; - if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT; - if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT; - if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD; - if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT; - if (acb & ACB_USE_DES_KEY_ONLY) uf |= UF_USE_DES_KEY_ONLY; - if (acb & ACB_SMARTCARD_REQUIRED) uf |= UF_SMARTCARD_REQUIRED; - if (acb & ACB_TRUSTED_FOR_DELEGATION) uf |= UF_TRUSTED_FOR_DELEGATION; - if (acb & ACB_DONT_REQUIRE_PREAUTH) uf |= UF_DONT_REQUIRE_PREAUTH; - if (acb & ACB_NO_AUTH_DATA_REQD) uf |= UF_NO_AUTH_DATA_REQUIRED; - if (acb & ACB_NOT_DELEGATED) uf |= UF_NOT_DELEGATED; - if (acb & ACB_ENC_TXT_PWD_ALLOWED) uf |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED; - - return uf; -} - -/* -translated the UserFlags (userAccountControl) to ACB_CTRL Flags -*/ -uint32 ads_uf2acb(uint32 uf) -{ - uint32 acb = 0x00000000; - - if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED; - if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ; - if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ; - if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS; - if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP; - if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK; - if (uf & UF_USE_DES_KEY_ONLY) acb |= ACB_USE_DES_KEY_ONLY; - if (uf & UF_SMARTCARD_REQUIRED) acb |= ACB_SMARTCARD_REQUIRED; - if (uf & UF_TRUSTED_FOR_DELEGATION) acb |= ACB_TRUSTED_FOR_DELEGATION; - if (uf & UF_DONT_REQUIRE_PREAUTH) acb |= ACB_DONT_REQUIRE_PREAUTH; - if (uf & UF_NO_AUTH_DATA_REQUIRED) acb |= ACB_NO_AUTH_DATA_REQD; - if (uf & UF_NOT_DELEGATED) acb |= ACB_NOT_DELEGATED; - if (uf & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED) acb |= ACB_ENC_TXT_PWD_ALLOWED; - - switch (uf & UF_ACCOUNT_TYPE_MASK) - { - case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break; - case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break; - case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break; - case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break; - case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break; - /*Fix Me: what should we do here? */ - default: acb |= ACB_NORMAL;break; - } - - return acb; -} - -/* -get the accountType from the UserFlags -*/ -uint32 ads_uf2atype(uint32 uf) -{ - uint32 atype = 0x00000000; - - if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT; - else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT; - else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST; - else if (uf & UF_WORKSTATION_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST; - else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST; - - return atype; -} - -/* -get the accountType from the groupType -*/ -uint32 ads_gtype2atype(uint32 gtype) -{ - uint32 atype = 0x00000000; - - switch(gtype) { - case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: - atype = ATYPE_SECURITY_LOCAL_GROUP; - break; - case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: - atype = ATYPE_SECURITY_LOCAL_GROUP; - break; - case GTYPE_SECURITY_GLOBAL_GROUP: - atype = ATYPE_SECURITY_GLOBAL_GROUP; - break; - - case GTYPE_DISTRIBUTION_GLOBAL_GROUP: - atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP; - break; - case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP: - atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP; - break; - case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP: - atype = ATYPE_DISTRIBUTION_LOCAL_GROUP; - break; - } - - return atype; -} - -/* turn a sAMAccountType into a SID_NAME_USE */ -enum lsa_SidType ads_atype_map(uint32 atype) -{ - switch (atype & 0xF0000000) { - case ATYPE_GLOBAL_GROUP: - return SID_NAME_DOM_GRP; - case ATYPE_SECURITY_LOCAL_GROUP: - return SID_NAME_ALIAS; - case ATYPE_ACCOUNT: - return SID_NAME_USER; - default: - DEBUG(1,("hmm, need to map account type 0x%x\n", atype)); - } - return SID_NAME_UNKNOWN; -} diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c index 39472b20d7..9fa3ddd9a8 100644 --- a/source3/lib/netapi/user.c +++ b/source3/lib/netapi/user.c @@ -770,7 +770,7 @@ static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb) { uint32_t fl = UF_SCRIPT; /* god knows why */ - fl |= ads_acb2uf(acb); + fl |= ds_acb2uf(acb); return fl; } diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index ddfeb8ed80..4f7c210915 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -250,7 +250,7 @@ static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m, DEBUG(10, ("Could not pull userAccountControl\n")); goto fail; } - pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET); + pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET); if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) { if (blob.length != NT_HASH_LEN) { @@ -310,7 +310,7 @@ static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state, ret &= tldap_make_mod_fmt( existing, mem_ctx, pnum_mods, pmods, "userAccountControl", - "%d", ads_acb2uf(pdb_get_acct_ctrl(sam))); + "%d", ds_acb2uf(pdb_get_acct_ctrl(sam))); ret &= tldap_make_mod_fmt( existing, mem_ctx, pnum_mods, pmods, "homeDirectory", @@ -1682,7 +1682,7 @@ static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m, DEBUG(10, ("no samAccountType")); continue; } - lsa_attrs[i] = ads_atype_map(attr); + lsa_attrs[i] = ds_atype_map(attr); num_mapped += 1; } diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index edd70667c0..08afb46674 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -210,7 +210,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, gid_t primary_gid = (gid_t)-1; if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) || - ads_atype_map(atype) != SID_NAME_USER) { + ds_atype_map(atype) != SID_NAME_USER) { DEBUG(1,("Not a user account? atype=0x%x\n", atype)); continue; } diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index 8a21ea55c9..b1a46c3c31 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -189,7 +189,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, "(!(userAccountControl:" LDB_OID_COMPARATOR_AND ":=%u))" "(userAccountControl:" LDB_OID_COMPARATOR_OR ":=%u))", ldb_binary_encode_string(mem_ctx, user), - UF_ACCOUNTDISABLE, samdb_acb2uf(acct_control)); + UF_ACCOUNTDISABLE, ds_acb2uf(acct_control)); if (ret != LDB_SUCCESS) { DEBUG(2,("Unable to find referece to user '%s' with ACB 0x%8x under %s: %s\n", user, acct_control, ldb_dn_get_linearized(dom_res->msgs[0]->dn), diff --git a/source4/dsdb/common/flag_mapping.c b/source4/dsdb/common/flag_mapping.c deleted file mode 100644 index af284c41e7..0000000000 --- a/source4/dsdb/common/flag_mapping.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - Unix SMB/CIFS implementation. - helper mapping functions for the SAMDB server - - Copyright (C) Stefan (metze) Metzmacher 2002 - Copyright (C) Andrew Tridgell 2004 - - 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 "librpc/gen_ndr/samr.h" -#include "../libds/common/flags.h" -#include "lib/ldb/include/ldb.h" -#include "dsdb/common/proto.h" - -/* -translated the ACB_CTRL Flags to UserFlags (userAccountControl) -*/ -/* mapping between ADS userAccountControl and SAMR acct_flags */ -static const struct { - uint32_t uf; - uint32_t acb; -} acct_flags_map[] = { - { UF_ACCOUNTDISABLE, ACB_DISABLED }, - { UF_HOMEDIR_REQUIRED, ACB_HOMDIRREQ }, - { UF_PASSWD_NOTREQD, ACB_PWNOTREQ }, - { UF_TEMP_DUPLICATE_ACCOUNT, ACB_TEMPDUP }, - { UF_NORMAL_ACCOUNT, ACB_NORMAL }, - { UF_MNS_LOGON_ACCOUNT, ACB_MNS }, - { UF_INTERDOMAIN_TRUST_ACCOUNT, ACB_DOMTRUST }, - { UF_WORKSTATION_TRUST_ACCOUNT, ACB_WSTRUST }, - { UF_SERVER_TRUST_ACCOUNT, ACB_SVRTRUST }, - { UF_DONT_EXPIRE_PASSWD, ACB_PWNOEXP }, - { UF_LOCKOUT, ACB_AUTOLOCK }, - { UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, ACB_ENC_TXT_PWD_ALLOWED }, - { UF_SMARTCARD_REQUIRED, ACB_SMARTCARD_REQUIRED }, - { UF_TRUSTED_FOR_DELEGATION, ACB_TRUSTED_FOR_DELEGATION }, - { UF_NOT_DELEGATED, ACB_NOT_DELEGATED }, - { UF_USE_DES_KEY_ONLY, ACB_USE_DES_KEY_ONLY}, - { UF_DONT_REQUIRE_PREAUTH, ACB_DONT_REQUIRE_PREAUTH }, - { UF_PASSWORD_EXPIRED, ACB_PW_EXPIRED }, - { UF_NO_AUTH_DATA_REQUIRED, ACB_NO_AUTH_DATA_REQD } -}; - -uint32_t samdb_acb2uf(uint32_t acb) -{ - uint32_t i, ret = 0; - for (i=0;imsg, ac->msg, "sAMAccountType", @@ -590,7 +590,7 @@ static int samldb_check_samAccountType(struct samldb_ctx *ac) "groupType invalid"); return LDB_ERR_UNWILLING_TO_PERFORM; } else { - account_type = samdb_gtype2atype(group_type); + account_type = ds_gtype2atype(group_type); ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, "sAMAccountType", @@ -1280,7 +1280,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) req->op.mod.message = msg = ldb_msg_copy_shallow(req, req->op.mod.message); group_type = strtoul((const char *)el->values[0].data, NULL, 0); - account_type = samdb_gtype2atype(group_type); + account_type = ds_gtype2atype(group_type); ret = samdb_msg_add_uint(ldb, msg, msg, "sAMAccountType", account_type); @@ -1296,7 +1296,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) req->op.mod.message = msg = ldb_msg_copy_shallow(req, req->op.mod.message); user_account_control = strtoul((const char *)el->values[0].data, NULL, 0); - account_type = samdb_uf2atype(user_account_control); + account_type = ds_uf2atype(user_account_control); ret = samdb_msg_add_uint(ldb, msg, msg, "sAMAccountType", account_type); diff --git a/source4/rpc_server/lsa/lsa_lookup.c b/source4/rpc_server/lsa/lsa_lookup.c index dc47d3783a..005c7d4f06 100644 --- a/source4/rpc_server/lsa/lsa_lookup.c +++ b/source4/rpc_server/lsa/lsa_lookup.c @@ -394,7 +394,7 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct tevent_context *ev_ctx, atype = samdb_result_uint(res[i], "sAMAccountType", 0); - *rtype = samdb_atype_map(atype); + *rtype = ds_atype_map(atype); if (*rtype == SID_NAME_UNKNOWN) { return STATUS_SOME_UNMAPPED; } @@ -503,7 +503,7 @@ static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX atype = samdb_result_uint(res[0], "sAMAccountType", 0); - *rtype = samdb_atype_map(atype); + *rtype = ds_atype_map(atype); return NT_STATUS_OK; } diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 489247c1d0..c755601230 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -1360,7 +1360,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL UF_INTERDOMAIN_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT | UF_SERVER_TRUST_ACCOUNT)); - user_account_control |= samdb_acb2uf(r->in.acct_flags); + user_account_control |= ds_acb2uf(r->in.acct_flags); talloc_free(msg); msg = ldb_msg_new(mem_ctx); @@ -1876,7 +1876,7 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL continue; } - rtype = samdb_atype_map(atype); + rtype = ds_atype_map(atype); if (rtype == SID_NAME_UNKNOWN) { status = STATUS_SOME_UNMAPPED; @@ -1962,7 +1962,7 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO continue; } - ids[i] = samdb_atype_map(atype); + ids[i] = ds_atype_map(atype); if (ids[i] == SID_NAME_UNKNOWN) { status = STATUS_SOME_UNMAPPED; -- cgit From f7ff6bd1425cc4f0aa13ce8e7498cdac3967acf3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 29 Jun 2009 20:34:03 +0200 Subject: s3-rpc_server: pass down full unix token to map_max_allowed_access(). Also use unix_token->uid instead of geteuid() when checking for mapping of the SEC_FLAG_MAXIMUM_ALLOWED flag. Guenther --- source3/include/proto.h | 5 +++-- source3/rpc_server/srv_lsa_nt.c | 8 ++++++-- source3/rpc_server/srv_samr_nt.c | 42 ++++++++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 44132b6519..c0ce35a865 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7253,8 +7253,9 @@ NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token, SE_PRIV *rights, uint32 rights_mask, uint32 des_access, uint32 *acc_granted, const char *debug); -void map_max_allowed_access(const NT_USER_TOKEN *token, - uint32_t *pacc_requested); +void map_max_allowed_access(const NT_USER_TOKEN *nt_token, + const struct unix_user_token *unix_token, + uint32_t *pacc_requested); /* The following definitions come from ../libds/common/flag_mapping.c */ diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 324483b3ee..c62991ee01 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -349,7 +349,9 @@ NTSTATUS _lsa_OpenPolicy2(pipes_struct *p, NTSTATUS status; /* Work out max allowed. */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); /* map the generic bits to the lsa policy ones */ se_map_generic(&des_access, &lsa_policy_mapping); @@ -1628,7 +1630,9 @@ NTSTATUS _lsa_OpenAccount(pipes_struct *p, * handle - so don't check against policy handle. */ /* Work out max allowed. */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); /* map the generic bits to the lsa account ones */ se_map_generic(&des_access, &lsa_account_mapping); diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 8560ee97c6..1085251421 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -236,8 +236,9 @@ done: Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set. ********************************************************************/ -void map_max_allowed_access(const NT_USER_TOKEN *token, - uint32_t *pacc_requested) +void map_max_allowed_access(const NT_USER_TOKEN *nt_token, + const struct unix_user_token *unix_token, + uint32_t *pacc_requested) { if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) { return; @@ -248,15 +249,15 @@ void map_max_allowed_access(const NT_USER_TOKEN *token, *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS; /* root gets anything. */ - if (geteuid() == sec_initial_uid()) { + if (unix_token->uid == sec_initial_uid()) { *pacc_requested |= GENERIC_ALL_ACCESS; return; } /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */ - if (is_sid_in_token(token, &global_sid_Builtin_Administrators) || - is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) { + if (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) || + is_sid_in_token(nt_token, &global_sid_Builtin_Account_Operators)) { *pacc_requested |= GENERIC_ALL_ACCESS; return; } @@ -266,7 +267,7 @@ void map_max_allowed_access(const NT_USER_TOKEN *token, DOM_SID domadmin_sid; sid_copy( &domadmin_sid, get_global_sam_sid() ); sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS ); - if (is_sid_in_token(token, &domadmin_sid)) { + if (is_sid_in_token(nt_token, &domadmin_sid)) { *pacc_requested |= GENERIC_ALL_ACCESS; return; } @@ -550,7 +551,9 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p, } /*check if access can be granted as requested by client. */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 ); se_map_generic( &des_access, &dom_generic_mapping ); @@ -2260,8 +2263,9 @@ NTSTATUS _samr_OpenUser(pipes_struct *p, return NT_STATUS_NO_SUCH_USER; /* check if access can be granted as requested by client. */ - - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW); se_map_generic(&des_access, &usr_generic_mapping); @@ -3834,7 +3838,9 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p, sid_compose(&sid, get_global_sam_sid(), *r->out.rid); - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW); @@ -3914,7 +3920,9 @@ NTSTATUS _samr_Connect(pipes_struct *p, was observed from a win98 client trying to enumerate users (when configured user level access control on shares) --jerry */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); se_map_generic( &des_access, &sam_generic_mapping ); @@ -3974,7 +3982,9 @@ NTSTATUS _samr_Connect2(pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); se_map_generic(&des_access, &sam_generic_mapping); @@ -4187,7 +4197,9 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p, /*check if access can be granted as requested by client. */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0); se_map_generic(&des_access,&ali_generic_mapping); @@ -6237,7 +6249,9 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p, } /*check if access can be granted as requested by client. */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0); se_map_generic(&des_access,&grp_generic_mapping); -- cgit From 8646b9521d267284a335aafba3df6039c41b8370 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 13:24:19 +0200 Subject: s3:net: Fix Bug #6222. Default to DRSUAPI replication for net rpc vampire keytab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit metze Signed-off-by: Günther Deschner --- source3/utils/net_rpc_samsync.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index bd5047c1ff..c0de247e7f 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -493,17 +493,20 @@ int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv) if (!dc_info.is_ad) { printf("DC is not running Active Directory\n"); - return -1; - } - - if (dc_info.is_mixed_mode) { ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id, 0, rpc_vampire_keytab_internals, argc, argv); + return -1; } else { ret = run_rpc_command(c, cli, &ndr_table_drsuapi.syntax_id, NET_FLAGS_SEAL, rpc_vampire_keytab_ds_internals, argc, argv); + if (ret != 0 && dc_info.is_mixed_mode) { + printf("Fallback to NT4 vampire on Mixed-Mode AD Domain\n"); + ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id, + 0, + rpc_vampire_keytab_internals, argc, argv); + } } return ret; -- cgit From e4fca7466d3bc064587638560572813e62df00d8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 13 Jul 2009 21:56:31 +0200 Subject: s3-pdb_ads: set correct pdb field with the value from 'accountExpires' attribute. Guenther --- source3/passdb/pdb_ads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index 4f7c210915..66fdff181f 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -203,7 +203,7 @@ static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m, pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET); } if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) { - pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET); + pdb_set_kickoff_time(sam, tmp_time, PDB_SET); } str = tldap_talloc_single_attribute(entry, "displayName", -- cgit From b25e3b6c8a7a1dd31607dd344e6e767716dd645d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Jul 2009 17:17:37 -0700 Subject: Fix set_posix_lock check which had been reversed in the recent changes. Jeremy. --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 4dd0375067..a862c1466f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7277,7 +7277,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, case SMB_SET_POSIX_LOCK: { - if (fsp) { + if (!fsp) { return NT_STATUS_INVALID_LEVEL; } status = smb_set_posix_lock(conn, req, -- cgit From e67de63ba6c6de60400e7deb4664d259f6dfb638 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Jul 2009 18:43:10 -0700 Subject: Make cli_posix_lock/unlock asynchronous. Jeremy. --- source3/client/client.c | 4 +- source3/include/proto.h | 21 +++- source3/libsmb/clifile.c | 273 ++++++++++++++++++++++++++++++++++++---------- source3/torture/torture.c | 12 ++ 4 files changed, 247 insertions(+), 63 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index ed45f4e2ca..6b273b47b0 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2605,7 +2605,7 @@ static int cmd_lock(void) len = (uint64_t)strtol(buf, (char **)NULL, 16); - if (!cli_posix_lock(cli, fnum, start, len, true, lock_type)) { + if (!NT_STATUS_IS_OK(cli_posix_lock(cli, fnum, start, len, true, lock_type))) { d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli)); } @@ -2639,7 +2639,7 @@ static int cmd_unlock(void) len = (uint64_t)strtol(buf, (char **)NULL, 16); - if (!cli_posix_unlock(cli, fnum, start, len)) { + if (!NT_STATUS_IS_OK(cli_posix_unlock(cli, fnum, start, len))) { d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli)); } diff --git a/source3/include/proto.h b/source3/include/proto.h index c0ce35a865..7b3eaa0659 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2516,11 +2516,26 @@ bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t bool cli_lock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type); bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); -bool cli_posix_lock(struct cli_state *cli, uint16_t fnum, +struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len, + bool wait_lock, + enum brl_type lock_type); +NTSTATUS cli_posix_lock_recv(struct tevent_req *req); +NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len, bool wait_lock, enum brl_type lock_type); -bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); -bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen); +struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len); +NTSTATUS cli_posix_unlock_recv(struct tevent_req *req); +NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); struct tevent_req *cli_getattrE_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index af67fcb746..0e2b3640f2 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -2857,103 +2857,260 @@ bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_ Get/unlock a POSIX lock on a file - internal function. ****************************************************************************/ -static bool cli_posix_lock_internal(struct cli_state *cli, uint16_t fnum, - uint64_t offset, uint64_t len, bool wait_lock, enum brl_type lock_type) +struct posix_lock_state { + uint16_t setup; + uint8_t param[4]; + uint8_t data[POSIX_LOCK_DATA_SIZE]; +}; + +static void cli_posix_unlock_internal_done(struct tevent_req *subreq) { - unsigned int param_len = 4; - unsigned int data_len = POSIX_LOCK_DATA_SIZE; - uint16_t setup = TRANSACT2_SETFILEINFO; - char param[4]; - unsigned char data[POSIX_LOCK_DATA_SIZE]; - char *rparam=NULL, *rdata=NULL; - int saved_timeout = cli->timeout; + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct posix_lock_state *state = tevent_req_data(req, struct posix_lock_state); + NTSTATUS status; - SSVAL(param,0,fnum); - SSVAL(param,2,SMB_SET_POSIX_LOCK); + status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + tevent_req_done(req); +} + +static struct tevent_req *cli_posix_lock_internal_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len, + bool wait_lock, + enum brl_type lock_type) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct posix_lock_state *state = NULL; + req = tevent_req_create(mem_ctx, &state, struct posix_lock_state); + if (req == NULL) { + return NULL; + } + + /* Setup setup word. */ + SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO); + + /* Setup param array. */ + SSVAL(&state->param, 0, fnum); + SSVAL(&state->param, 2, SMB_SET_POSIX_LOCK); + + /* Setup data array. */ switch (lock_type) { case READ_LOCK: - SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_READ); + SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET, + POSIX_LOCK_TYPE_READ); break; case WRITE_LOCK: - SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_WRITE); + SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET, + POSIX_LOCK_TYPE_WRITE); break; case UNLOCK_LOCK: - SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK); + SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET, + POSIX_LOCK_TYPE_UNLOCK); break; default: - return False; + return NULL; } if (wait_lock) { - SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_WAIT); - cli->timeout = 0x7FFFFFFF; + SSVAL(&state->data, POSIX_LOCK_FLAGS_OFFSET, + POSIX_LOCK_FLAG_WAIT); } else { - SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_NOWAIT); - } - - SIVAL(data, POSIX_LOCK_PID_OFFSET, cli->pid); - SOFF_T(data, POSIX_LOCK_START_OFFSET, offset); - SOFF_T(data, POSIX_LOCK_LEN_OFFSET, len); - - if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ - )) { - cli->timeout = saved_timeout; - return False; - } + SSVAL(state->data, POSIX_LOCK_FLAGS_OFFSET, + POSIX_LOCK_FLAG_NOWAIT); + } + + SIVAL(&state->data, POSIX_LOCK_PID_OFFSET, cli->pid); + SOFF_T(&state->data, POSIX_LOCK_START_OFFSET, offset); + SOFF_T(&state->data, POSIX_LOCK_LEN_OFFSET, len); + + subreq = cli_trans_send(state, /* mem ctx. */ + ev, /* event ctx. */ + cli, /* cli_state. */ + SMBtrans2, /* cmd. */ + NULL, /* pipe name. */ + -1, /* fid. */ + 0, /* function. */ + 0, /* flags. */ + &state->setup, /* setup. */ + 1, /* num setup uint16_t words. */ + 0, /* max returned setup. */ + state->param, /* param. */ + 4, /* num param. */ + 2, /* max returned param. */ + state->data, /* data. */ + POSIX_LOCK_DATA_SIZE, /* num data. */ + 0); /* max returned data. */ - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - cli->timeout = saved_timeout; - SAFE_FREE(rdata); - SAFE_FREE(rparam); - return False; + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } - - cli->timeout = saved_timeout; - - SAFE_FREE(rdata); - SAFE_FREE(rparam); - - return True; + tevent_req_set_callback(subreq, cli_posix_unlock_internal_done, req); + return req; } /**************************************************************************** POSIX Lock a file. ****************************************************************************/ -bool cli_posix_lock(struct cli_state *cli, uint16_t fnum, +struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len, + bool wait_lock, + enum brl_type lock_type) +{ + return cli_posix_lock_internal_send(mem_ctx, ev, cli, fnum, offset, len, + wait_lock, lock_type); +} + +NTSTATUS cli_posix_lock_recv(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len, bool wait_lock, enum brl_type lock_type) { + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + if (lock_type != READ_LOCK && lock_type != WRITE_LOCK) { - return False; + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_posix_lock_send(frame, + ev, + cli, + fnum, + offset, + len, + wait_lock, + lock_type); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; } - return cli_posix_lock_internal(cli, fnum, offset, len, wait_lock, lock_type); + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_lock_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** POSIX Unlock a file. ****************************************************************************/ -bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len) +struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) { - return cli_posix_lock_internal(cli, fnum, offset, len, False, UNLOCK_LOCK); + return cli_posix_lock_internal_send(mem_ctx, ev, cli, fnum, offset, len, + false, UNLOCK_LOCK); } -/**************************************************************************** - POSIX Get any lock covering a file. -****************************************************************************/ +NTSTATUS cli_posix_unlock_recv(struct tevent_req *req) +{ + NTSTATUS status; -bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen) + if (tevent_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len) { - return True; + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_posix_unlock_send(frame, + ev, + cli, + fnum, + offset, + len); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_unlock_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 8e38093e33..8cebc2adcc 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -4295,6 +4295,18 @@ static bool run_simple_posix_open_test(int dummy) goto out; } + /* Do a POSIX lock/unlock. */ + if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, WRITE_LOCK))) { + printf("POSIX lock failed\n"); + goto out; + } + + /* Punch a hole in the locked area. */ + if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) { + printf("POSIX unlock failed\n"); + goto out; + } + cli_close(cli1, fnum1); /* Open the symlink for read - this should fail. A POSIX -- cgit From bd58a1461724eb92c9fedd014edb7465f5a16b40 Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Thu, 9 Jul 2009 14:45:23 +0200 Subject: reject ACLs with DESC_DACL_PROTECTED on GPFS as GPFS does not support the ACE4_FLAG_NO_PROPAGATE NFSv4 flag (which would be the mapping for the DESC_DACL_PROTECTED flag), the status of this flag is currently silently ignored by Samba. That means that if you deselect the "Allow inheritable permissions..." checkbox in Windows' ACL dialog and then apply the ACL, the flag will be back immediately. To make sure that automatic migration with e.g. robocopy does not lead to ACLs silently (and unintentionally) changed, this patch adds an explicit check for this flag and if set, it will return NT_STATUS_NOT_SUPPORTED so errors are shown up on the Windows side and the Administrator is aware of the ACLs not being settable like intended Signed-off-by: Christian Ambach --- source3/modules/vfs_gpfs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 47858cb352..ffa8db00b3 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -445,6 +445,11 @@ static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_i if (acl->acl_version&GPFS_ACL_VERSION_NFS4) { + if ((psd->type&SEC_DESC_DACL_PROTECTED)) { + DEBUG(2, ("Rejecting unsupported ACL with DACL_PROTECTED bit set\n")); + return NT_STATUS_NOT_SUPPORTED; + } + result = smb_set_nt_acl_nfs4( fsp, security_info_sent, psd, gpfsacl_process_smbacl); -- cgit From 05959636328ae71b1969a85241a93883f20bcb69 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 13 Jul 2009 22:46:51 +0200 Subject: samr: add missing samr_ValidationStatus codes. Guenther --- librpc/idl/samr.idl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/librpc/idl/samr.idl b/librpc/idl/samr.idl index b7c151d413..8a5692fe17 100644 --- a/librpc/idl/samr.idl +++ b/librpc/idl/samr.idl @@ -1544,12 +1544,14 @@ import "misc.idl", "lsa.idl", "security.idl"; SAMR_VALIDATION_STATUS_SUCCESS = 0, SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE = 1, SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT = 2, + SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED = 3, SAMR_VALIDATION_STATUS_BAD_PASSWORD = 4, SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT = 5, SAMR_VALIDATION_STATUS_PWD_TOO_SHORT = 6, SAMR_VALIDATION_STATUS_PWD_TOO_LONG = 7, SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH = 8, - SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9 + SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9, + SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR = 10 } samr_ValidationStatus; typedef struct { -- cgit From d7c366f8de13ce6f2cf691b95974a18e21d0fff7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 13 Jul 2009 23:38:16 +0200 Subject: s3: re-run make idl. Guenther --- librpc/gen_ndr/ndr_samr.c | 2 ++ librpc/gen_ndr/samr.h | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/librpc/gen_ndr/ndr_samr.c b/librpc/gen_ndr/ndr_samr.c index 58b7ae2413..258aba9bb6 100644 --- a/librpc/gen_ndr/ndr_samr.c +++ b/librpc/gen_ndr/ndr_samr.c @@ -4831,12 +4831,14 @@ _PUBLIC_ void ndr_print_samr_ValidationStatus(struct ndr_print *ndr, const char case SAMR_VALIDATION_STATUS_SUCCESS: val = "SAMR_VALIDATION_STATUS_SUCCESS"; break; case SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE: val = "SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE"; break; case SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT: val = "SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT"; break; + case SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED: val = "SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED"; break; case SAMR_VALIDATION_STATUS_BAD_PASSWORD: val = "SAMR_VALIDATION_STATUS_BAD_PASSWORD"; break; case SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT: val = "SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT"; break; case SAMR_VALIDATION_STATUS_PWD_TOO_SHORT: val = "SAMR_VALIDATION_STATUS_PWD_TOO_SHORT"; break; case SAMR_VALIDATION_STATUS_PWD_TOO_LONG: val = "SAMR_VALIDATION_STATUS_PWD_TOO_LONG"; break; case SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH: val = "SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH"; break; case SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT: val = "SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT"; break; + case SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR: val = "SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR"; break; } ndr_print_enum(ndr, name, "ENUM", val, r); } diff --git a/librpc/gen_ndr/samr.h b/librpc/gen_ndr/samr.h index e44de1b037..ce84b45a9e 100644 --- a/librpc/gen_ndr/samr.h +++ b/librpc/gen_ndr/samr.h @@ -834,24 +834,28 @@ enum samr_ValidationStatus SAMR_VALIDATION_STATUS_SUCCESS=0, SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE=1, SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT=2, + SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED=3, SAMR_VALIDATION_STATUS_BAD_PASSWORD=4, SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT=5, SAMR_VALIDATION_STATUS_PWD_TOO_SHORT=6, SAMR_VALIDATION_STATUS_PWD_TOO_LONG=7, SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH=8, - SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT=9 + SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT=9, + SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR=10 } #else { __donnot_use_enum_samr_ValidationStatus=0x7FFFFFFF} #define SAMR_VALIDATION_STATUS_SUCCESS ( 0 ) #define SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE ( 1 ) #define SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT ( 2 ) +#define SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED ( 3 ) #define SAMR_VALIDATION_STATUS_BAD_PASSWORD ( 4 ) #define SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT ( 5 ) #define SAMR_VALIDATION_STATUS_PWD_TOO_SHORT ( 6 ) #define SAMR_VALIDATION_STATUS_PWD_TOO_LONG ( 7 ) #define SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH ( 8 ) #define SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT ( 9 ) +#define SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR ( 10 ) #endif ; -- cgit From 39fa9468c6b8099429b971d75c0647033b60901c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 13 Jul 2009 23:42:57 +0200 Subject: s3-account_policy: remove trailing whitespace. Guenther --- source3/lib/account_pol.c | 64 +++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index 1e435ca53e..4b63375e29 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -1,20 +1,20 @@ -/* +/* * Unix SMB/CIFS implementation. * account policy storage * Copyright (C) Jean François Micouleau 1998-2001. * Copyright (C) Andrew Bartlett 2002 * Copyright (C) Guenther Deschner 2004-2005 - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 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 . */ @@ -39,51 +39,51 @@ struct ap_table { }; static const struct ap_table account_policy_names[] = { - {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH, - "Minimal password length (default: 5)", + {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH, + "Minimal password length (default: 5)", "sambaMinPwdLength" }, {AP_PASSWORD_HISTORY, "password history", 0, - "Length of Password History Entries (default: 0 => off)", + "Length of Password History Entries (default: 0 => off)", "sambaPwdHistoryLength" }, - + {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0, "Force Users to logon for password change (default: 0 => off, 2 => on)", "sambaLogonToChgPwd" }, - + {AP_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1, - "Maximum password age, in seconds (default: -1 => never expire passwords)", + "Maximum password age, in seconds (default: -1 => never expire passwords)", "sambaMaxPwdAge" }, - + {AP_MIN_PASSWORD_AGE,"minimum password age", 0, - "Minimal password age, in seconds (default: 0 => allow immediate password change)", + "Minimal password age, in seconds (default: 0 => allow immediate password change)", "sambaMinPwdAge" }, - + {AP_LOCK_ACCOUNT_DURATION, "lockout duration", 30, "Lockout duration in minutes (default: 30, -1 => forever)", "sambaLockoutDuration" }, - + {AP_RESET_COUNT_TIME, "reset count minutes", 30, - "Reset time after lockout in minutes (default: 30)", + "Reset time after lockout in minutes (default: 30)", "sambaLockoutObservationWindow" }, - + {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0, - "Lockout users after bad logon attempts (default: 0 => off)", + "Lockout users after bad logon attempts (default: 0 => off)", "sambaLockoutThreshold" }, - + {AP_TIME_TO_LOGOUT, "disconnect time", (uint32) -1, - "Disconnect Users outside logon hours (default: -1 => off, 0 => on)", - "sambaForceLogoff" }, - + "Disconnect Users outside logon hours (default: -1 => off, 0 => on)", + "sambaForceLogoff" }, + {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0, "Allow Machine Password changes (default: 0 => off)", "sambaRefuseMachinePwdChange" }, - + {0, NULL, 0, "", NULL} }; void account_policy_names_list(const char ***names, int *num_names) -{ +{ const char **nl; int i, count; @@ -175,7 +175,7 @@ bool account_policy_get_default(int account_policy, uint32 *val) return True; } } - DEBUG(0,("no default for account_policy index %d found. This should never happen\n", + DEBUG(0,("no default for account_policy index %d found. This should never happen\n", account_policy)); return False; } @@ -189,7 +189,7 @@ static bool account_policy_set_default_on_empty(int account_policy) uint32 value; - if (!account_policy_get(account_policy, &value) && + if (!account_policy_get(account_policy, &value) && !account_policy_get_default(account_policy, &value)) { return False; } @@ -299,7 +299,7 @@ bool init_account_policy(void) } /***************************************************************************** -Get an account policy (from tdb) +Get an account policy (from tdb) *****************************************************************************/ bool account_policy_get(int field, uint32 *value) @@ -320,12 +320,12 @@ bool account_policy_get(int field, uint32 *value) DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field)); return False; } - + if (!dbwrap_fetch_uint32(db, name, ®val)) { DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name)); return False; } - + if (value) { *value = regval; } @@ -336,7 +336,7 @@ bool account_policy_get(int field, uint32 *value) /**************************************************************************** -Set an account policy (in tdb) +Set an account policy (in tdb) ****************************************************************************/ bool account_policy_set(int field, uint32 value) @@ -362,12 +362,12 @@ bool account_policy_set(int field, uint32 value) } DEBUG(10,("account_policy_set: name: %s, value: %d\n", name, value)); - + return True; } /**************************************************************************** -Set an account policy in the cache +Set an account policy in the cache ****************************************************************************/ bool cache_account_policy_set(int field, uint32 value) @@ -404,7 +404,7 @@ bool cache_account_policy_set(int field, uint32 value) } /***************************************************************************** -Get an account policy from the cache +Get an account policy from the cache *****************************************************************************/ bool cache_account_policy_get(int field, uint32 *value) -- cgit From 9f15ef11bdf75dbc1a1af3c2bc35b1d653216f62 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 13 Jul 2009 23:53:49 +0200 Subject: s3-account_policy: add pdb_policy_type enum. Guenther --- source3/include/passdb.h | 22 ++++++- source3/include/proto.h | 22 +++---- source3/include/smb.h | 14 ---- source3/lib/account_pol.c | 88 +++++++++++++------------- source3/libnet/libnet_samsync_passdb.c | 23 ++++--- source3/passdb/passdb.c | 16 ++--- source3/passdb/pdb_ads.c | 10 +-- source3/passdb/pdb_get_set.c | 6 +- source3/passdb/pdb_interface.c | 16 ++--- source3/passdb/pdb_ldap.c | 40 ++++++------ source3/registry/reg_backend_netlogon_params.c | 2 +- source3/rpc_server/srv_samr_nt.c | 62 +++++++++--------- source3/rpc_server/srv_samr_util.c | 2 +- source3/smbd/chgpasswd.c | 6 +- source3/torture/pdbtest.c | 6 +- source3/winbindd/winbindd_passdb.c | 10 +-- 16 files changed, 179 insertions(+), 166 deletions(-) diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 4e53311eba..2b4f9c2e43 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -205,6 +205,22 @@ struct pdb_domain_info { struct GUID guid; }; +/* + * Types of account policy. + */ +enum pdb_policy_type { + PDB_POLICY_MIN_PASSWORD_LEN = 1, + PDB_POLICY_PASSWORD_HISTORY = 2, + PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS = 3, + PDB_POLICY_MAX_PASSWORD_AGE = 4, + PDB_POLICY_MIN_PASSWORD_AGE = 5, + PDB_POLICY_LOCK_ACCOUNT_DURATION = 6, + PDB_POLICY_RESET_COUNT_TIME = 7, + PDB_POLICY_BAD_ATTEMPT_LOCKOUT = 8, + PDB_POLICY_TIME_TO_LOGOUT = 9, + PDB_POLICY_REFUSE_MACHINE_PW_CHANGE = 10 +}; + #define PDB_CAP_STORE_RIDS 0x0001 #define PDB_CAP_ADS 0x0002 @@ -351,10 +367,12 @@ struct pdb_methods enum lsa_SidType *attrs); NTSTATUS (*get_account_policy)(struct pdb_methods *methods, - int policy_index, uint32 *value); + enum pdb_policy_type type, + uint32_t *value); NTSTATUS (*set_account_policy)(struct pdb_methods *methods, - int policy_index, uint32 value); + enum pdb_policy_type type, + uint32_t value); NTSTATUS (*get_seq_num)(struct pdb_methods *methods, time_t *seq_num); diff --git a/source3/include/proto.h b/source3/include/proto.h index 7b3eaa0659..0dd1e98c86 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -290,16 +290,16 @@ bool check_access(int sock, const char **allow_list, const char **deny_list); /* The following definitions come from lib/account_pol.c */ void account_policy_names_list(const char ***names, int *num_names); -const char *decode_account_policy_name(int field); -const char *get_account_policy_attr(int field); -const char *account_policy_get_desc(int field); -int account_policy_name_to_fieldnum(const char *name); -bool account_policy_get_default(int account_policy, uint32 *val); +const char *decode_account_policy_name(enum pdb_policy_type type); +const char *get_account_policy_attr(enum pdb_policy_type type); +const char *account_policy_get_desc(enum pdb_policy_type type); +enum pdb_policy_type account_policy_name_to_typenum(const char *name); +bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val); bool init_account_policy(void); -bool account_policy_get(int field, uint32 *value); -bool account_policy_set(int field, uint32 value); -bool cache_account_policy_set(int field, uint32 value); -bool cache_account_policy_get(int field, uint32 *value); +bool account_policy_get(enum pdb_policy_type type, uint32_t *value); +bool account_policy_set(enum pdb_policy_type type, uint32_t value); +bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value); +bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value); struct db_context *get_account_pol_db( void ); /* The following definitions come from lib/adt_tree.c */ @@ -4595,8 +4595,8 @@ NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid, const char **names, uint32 *rids, enum lsa_SidType *attrs); -bool pdb_get_account_policy(int policy_index, uint32 *value); -bool pdb_set_account_policy(int policy_index, uint32 value); +bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value); +bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value); bool pdb_get_seq_num(time_t *seq_num); bool pdb_uid_to_rid(uid_t uid, uint32 *rid); bool pdb_uid_to_sid(uid_t uid, DOM_SID *sid); diff --git a/source3/include/smb.h b/source3/include/smb.h index 9afeb67b00..2e9cf1b54a 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -833,20 +833,6 @@ struct pipe_open_rec { #define PW_HISTORY_ENTRY_LEN (PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN) #define MAX_PW_HISTORY_LEN 24 -/* - * Flags for account policy. - */ -#define AP_MIN_PASSWORD_LEN 1 -#define AP_PASSWORD_HISTORY 2 -#define AP_USER_MUST_LOGON_TO_CHG_PASS 3 -#define AP_MAX_PASSWORD_AGE 4 -#define AP_MIN_PASSWORD_AGE 5 -#define AP_LOCK_ACCOUNT_DURATION 6 -#define AP_RESET_COUNT_TIME 7 -#define AP_BAD_ATTEMPT_LOCKOUT 8 -#define AP_TIME_TO_LOGOUT 9 -#define AP_REFUSE_MACHINE_PW_CHANGE 10 - /* * Flags for local user manipulation. */ diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index 4b63375e29..f4101e96bc 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -31,7 +31,7 @@ static struct db_context *db; struct ap_table { - int field; + enum pdb_policy_type type; const char *string; uint32 default_val; const char *description; @@ -39,43 +39,43 @@ struct ap_table { }; static const struct ap_table account_policy_names[] = { - {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH, + {PDB_POLICY_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH, "Minimal password length (default: 5)", "sambaMinPwdLength" }, - {AP_PASSWORD_HISTORY, "password history", 0, + {PDB_POLICY_PASSWORD_HISTORY, "password history", 0, "Length of Password History Entries (default: 0 => off)", "sambaPwdHistoryLength" }, - {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0, + {PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0, "Force Users to logon for password change (default: 0 => off, 2 => on)", "sambaLogonToChgPwd" }, - {AP_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1, + {PDB_POLICY_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1, "Maximum password age, in seconds (default: -1 => never expire passwords)", "sambaMaxPwdAge" }, - {AP_MIN_PASSWORD_AGE,"minimum password age", 0, + {PDB_POLICY_MIN_PASSWORD_AGE,"minimum password age", 0, "Minimal password age, in seconds (default: 0 => allow immediate password change)", "sambaMinPwdAge" }, - {AP_LOCK_ACCOUNT_DURATION, "lockout duration", 30, + {PDB_POLICY_LOCK_ACCOUNT_DURATION, "lockout duration", 30, "Lockout duration in minutes (default: 30, -1 => forever)", "sambaLockoutDuration" }, - {AP_RESET_COUNT_TIME, "reset count minutes", 30, + {PDB_POLICY_RESET_COUNT_TIME, "reset count minutes", 30, "Reset time after lockout in minutes (default: 30)", "sambaLockoutObservationWindow" }, - {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0, + {PDB_POLICY_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0, "Lockout users after bad logon attempts (default: 0 => off)", "sambaLockoutThreshold" }, - {AP_TIME_TO_LOGOUT, "disconnect time", (uint32) -1, + {PDB_POLICY_TIME_TO_LOGOUT, "disconnect time", (uint32) -1, "Disconnect Users outside logon hours (default: -1 => off, 0 => on)", "sambaForceLogoff" }, - {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0, + {PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0, "Allow Machine Password changes (default: 0 => off)", "sambaRefuseMachinePwdChange" }, @@ -106,11 +106,11 @@ void account_policy_names_list(const char ***names, int *num_names) Get the account policy name as a string from its #define'ed number ****************************************************************************/ -const char *decode_account_policy_name(int field) +const char *decode_account_policy_name(enum pdb_policy_type type) { int i; for (i=0; account_policy_names[i].string; i++) { - if (field == account_policy_names[i].field) { + if (type == account_policy_names[i].type) { return account_policy_names[i].string; } } @@ -121,11 +121,11 @@ const char *decode_account_policy_name(int field) Get the account policy LDAP attribute as a string from its #define'ed number ****************************************************************************/ -const char *get_account_policy_attr(int field) +const char *get_account_policy_attr(enum pdb_policy_type type) { int i; - for (i=0; account_policy_names[i].field; i++) { - if (field == account_policy_names[i].field) { + for (i=0; account_policy_names[i].type; i++) { + if (type == account_policy_names[i].type) { return account_policy_names[i].ldap_attr; } } @@ -136,11 +136,11 @@ const char *get_account_policy_attr(int field) Get the account policy description as a string from its #define'ed number ****************************************************************************/ -const char *account_policy_get_desc(int field) +const char *account_policy_get_desc(enum pdb_policy_type type) { int i; for (i=0; account_policy_names[i].string; i++) { - if (field == account_policy_names[i].field) { + if (type == account_policy_names[i].type) { return account_policy_names[i].description; } } @@ -151,12 +151,12 @@ const char *account_policy_get_desc(int field) Get the account policy name as a string from its #define'ed number ****************************************************************************/ -int account_policy_name_to_fieldnum(const char *name) +enum pdb_policy_type account_policy_name_to_typenum(const char *name) { int i; for (i=0; account_policy_names[i].string; i++) { if (strcmp(name, account_policy_names[i].string) == 0) { - return account_policy_names[i].field; + return account_policy_names[i].type; } } return 0; @@ -166,35 +166,35 @@ int account_policy_name_to_fieldnum(const char *name) Get default value for account policy *****************************************************************************/ -bool account_policy_get_default(int account_policy, uint32 *val) +bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val) { int i; - for (i=0; account_policy_names[i].field; i++) { - if (account_policy_names[i].field == account_policy) { + for (i=0; account_policy_names[i].type; i++) { + if (account_policy_names[i].type == type) { *val = account_policy_names[i].default_val; return True; } } DEBUG(0,("no default for account_policy index %d found. This should never happen\n", - account_policy)); + type)); return False; } /***************************************************************************** - Set default for a field if it is empty + Set default for a type if it is empty *****************************************************************************/ -static bool account_policy_set_default_on_empty(int account_policy) +static bool account_policy_set_default_on_empty(enum pdb_policy_type type) { uint32 value; - if (!account_policy_get(account_policy, &value) && - !account_policy_get_default(account_policy, &value)) { + if (!account_policy_get(type, &value) && + !account_policy_get_default(type, &value)) { return False; } - return account_policy_set(account_policy, value); + return account_policy_set(type, value); } /***************************************************************************** @@ -255,9 +255,9 @@ bool init_account_policy(void) goto cancel; } - for (i=0; account_policy_names[i].field; i++) { + for (i=0; account_policy_names[i].type; i++) { - if (!account_policy_set_default_on_empty(account_policy_names[i].field)) { + if (!account_policy_set_default_on_empty(account_policy_names[i].type)) { DEBUG(0,("failed to set default value in account policy tdb\n")); goto cancel; } @@ -302,7 +302,7 @@ bool init_account_policy(void) Get an account policy (from tdb) *****************************************************************************/ -bool account_policy_get(int field, uint32 *value) +bool account_policy_get(enum pdb_policy_type type, uint32_t *value) { const char *name; uint32 regval; @@ -315,14 +315,14 @@ bool account_policy_get(int field, uint32 *value) *value = 0; } - name = decode_account_policy_name(field); + name = decode_account_policy_name(type); if (name == NULL) { - DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field)); + DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", type)); return False; } if (!dbwrap_fetch_uint32(db, name, ®val)) { - DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name)); + DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for type %d (%s), returning 0\n", type, name)); return False; } @@ -339,7 +339,7 @@ bool account_policy_get(int field, uint32 *value) Set an account policy (in tdb) ****************************************************************************/ -bool account_policy_set(int field, uint32 value) +bool account_policy_set(enum pdb_policy_type type, uint32_t value) { const char *name; NTSTATUS status; @@ -348,16 +348,16 @@ bool account_policy_set(int field, uint32 value) return False; } - name = decode_account_policy_name(field); + name = decode_account_policy_name(type); if (name == NULL) { - DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", field)); + DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", type)); return False; } status = dbwrap_trans_store_uint32(db, name, value); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("store_uint32 failed for field %d (%s) on value " - "%u: %s\n", field, name, value, nt_errstr(status))); + DEBUG(1, ("store_uint32 failed for type %d (%s) on value " + "%u: %s\n", type, name, value, nt_errstr(status))); return False; } @@ -370,14 +370,14 @@ bool account_policy_set(int field, uint32 value) Set an account policy in the cache ****************************************************************************/ -bool cache_account_policy_set(int field, uint32 value) +bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value) { const char *policy_name = NULL; char *cache_key = NULL; char *cache_value = NULL; bool ret = False; - policy_name = decode_account_policy_name(field); + policy_name = decode_account_policy_name(type); if (policy_name == NULL) { DEBUG(0,("cache_account_policy_set: no policy found\n")); return False; @@ -407,14 +407,14 @@ bool cache_account_policy_set(int field, uint32 value) Get an account policy from the cache *****************************************************************************/ -bool cache_account_policy_get(int field, uint32 *value) +bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value) { const char *policy_name = NULL; char *cache_key = NULL; char *cache_value = NULL; bool ret = False; - policy_name = decode_account_policy_name(field); + policy_name = decode_account_policy_name(type); if (policy_name == NULL) { DEBUG(0,("cache_account_policy_set: no policy found\n")); return False; diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c index 27c7aac7e7..41a9b3d9f3 100644 --- a/source3/libnet/libnet_samsync_passdb.c +++ b/source3/libnet/libnet_samsync_passdb.c @@ -676,21 +676,24 @@ static NTSTATUS fetch_domain_info(TALLOC_CTX *mem_ctx, } - if (!pdb_set_account_policy(AP_PASSWORD_HISTORY, + if (!pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY, r->password_history_length)) return nt_status; - if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN, + if (!pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, r->min_password_length)) return nt_status; - if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age)) + if (!pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, + (uint32)u_max_age)) return nt_status; - if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (uint32)u_min_age)) + if (!pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, + (uint32)u_min_age)) return nt_status; - if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout)) + if (!pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, + (uint32)u_logout)) return nt_status; if (lockstr) { @@ -699,21 +702,23 @@ static NTSTATUS fetch_domain_info(TALLOC_CTX *mem_ctx, u_lockoutreset = uint64s_nt_time_to_unix_abs(&lockstr->reset_count); u_lockouttime = uint64s_nt_time_to_unix_abs((uint64_t *)&lockstr->lockout_duration); - if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, + if (!pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, lockstr->bad_attempt_lockout)) return nt_status; - if (!pdb_set_account_policy(AP_RESET_COUNT_TIME, (uint32_t)u_lockoutreset/60)) + if (!pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, + (uint32_t)u_lockoutreset/60)) return nt_status; if (u_lockouttime != -1) u_lockouttime /= 60; - if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32_t)u_lockouttime)) + if (!pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, + (uint32_t)u_lockouttime)) return nt_status; } - if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + if (!pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, r->logon_to_chgpass)) return nt_status; diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 4ed04e4e7a..0678181669 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1439,7 +1439,7 @@ static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 bu } /* Change from V1 is addition of password history field. */ - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen) { uint8 *pw_hist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN); if (!pw_hist) { @@ -1674,7 +1674,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu } } - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen) { uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN); if (!pw_hist) { @@ -1879,7 +1879,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool nt_pw_len = 0; } - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len); if (pwHistLen && nt_pw_hist && nt_pw_hist_len) { nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN; @@ -2085,7 +2085,7 @@ bool pdb_copy_sam_account(struct samu *dst, struct samu *src ) } /********************************************************************* - Update the bad password count checking the AP_RESET_COUNT_TIME + Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME *********************************************************************/ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated) @@ -2102,7 +2102,7 @@ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated) } become_root(); - res = pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime); + res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime); unbecome_root(); if (!res) { @@ -2131,7 +2131,7 @@ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated) } /********************************************************************* - Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION + Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION *********************************************************************/ bool pdb_update_autolock_flag(struct samu *sampass, bool *updated) @@ -2147,7 +2147,7 @@ bool pdb_update_autolock_flag(struct samu *sampass, bool *updated) } become_root(); - res = pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration); + res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration); unbecome_root(); if (!res) { @@ -2199,7 +2199,7 @@ bool pdb_increment_bad_password_count(struct samu *sampass) /* Retrieve the account lockout policy */ become_root(); - ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout); + ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout); unbecome_root(); if ( !ret ) { DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n")); diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index 66fdff181f..70d550042b 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -1706,16 +1706,18 @@ static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m, } static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m, - int policy_index, uint32 *value) + enum pdb_policy_type type, + uint32_t *value) { - return account_policy_get(policy_index, value) + return account_policy_get(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m, - int policy_index, uint32 value) + enum pdb_policy_type type, + uint32_t value) { - return account_policy_set(policy_index, value) + return account_policy_set(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index f55b77f675..30775e49fe 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -88,7 +88,7 @@ time_t pdb_get_pass_can_change_time(const struct samu *sampass) pdb_get_init_flags(sampass, PDB_CANCHANGETIME) == PDB_CHANGED) return sampass->pass_can_change_time; - if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow)) + if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &allow)) allow = 0; /* in normal cases, just calculate it from policy */ @@ -112,7 +112,7 @@ time_t pdb_get_pass_must_change_time(const struct samu *sampass) if (sampass->acct_ctrl & ACB_PWNOEXP) return get_time_t_max(); - if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire) + if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire) || expire == (uint32)-1 || expire == 0) return get_time_t_max(); @@ -1013,7 +1013,7 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext) if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) { uchar *pwhistory; uint32 pwHistLen; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen != 0){ uint32 current_history_len; /* We need to make sure we don't have a race condition here - the diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 465a6bf595..5d0b625da5 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -994,25 +994,25 @@ NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid, } #endif -bool pdb_get_account_policy(int policy_index, uint32 *value) +bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value) { struct pdb_methods *pdb = pdb_get_methods(); NTSTATUS status; become_root(); - status = pdb->get_account_policy(pdb, policy_index, value); + status = pdb->get_account_policy(pdb, type, value); unbecome_root(); return NT_STATUS_IS_OK(status); } -bool pdb_set_account_policy(int policy_index, uint32 value) +bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value) { struct pdb_methods *pdb = pdb_get_methods(); NTSTATUS status; become_root(); - status = pdb->set_account_policy(pdb, policy_index, value); + status = pdb->set_account_policy(pdb, type, value); unbecome_root(); return NT_STATUS_IS_OK(status); @@ -1174,14 +1174,14 @@ static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, return NT_STATUS_OK; } -static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value) +static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value) { - return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + return account_policy_get(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } -static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value) +static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value) { - return account_policy_set(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + return account_policy_set(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 173298561f..11554a76ac 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -902,7 +902,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state, pwHistLen = 0; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen > 0){ uint8 *pwhist = NULL; int i; @@ -1327,7 +1327,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, if (need_update(sampass, PDB_PWHISTORY)) { char *pwstr = NULL; uint32 pwHistLen = 0; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); pwstr = SMB_MALLOC_ARRAY(char, 1024); if (!pwstr) { @@ -1404,7 +1404,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, uint16 badcount = pdb_get_bad_password_count(sampass); time_t badtime = pdb_get_bad_password_time(sampass); uint32 pol; - pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol); + pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol); DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n", (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime)); @@ -3762,7 +3762,7 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods, } static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, - int policy_index, + enum pdb_policy_type type, uint32 value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; @@ -3780,7 +3780,7 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, return NT_STATUS_INVALID_PARAMETER; } - policy_attr = get_account_policy_attr(policy_index); + policy_attr = get_account_policy_attr(type); if (policy_attr == NULL) { DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid " "policy\n")); @@ -3800,7 +3800,7 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, return ntstatus; } - if (!cache_account_policy_set(policy_index, value)) { + if (!cache_account_policy_set(type, value)) { DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to " "update local tdb cache\n")); return ntstatus; @@ -3810,14 +3810,15 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, } static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, - int policy_index, uint32 value) + enum pdb_policy_type type, + uint32_t value) { - return ldapsam_set_account_policy_in_ldap(methods, policy_index, + return ldapsam_set_account_policy_in_ldap(methods, type, value); } static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods, - int policy_index, + enum pdb_policy_type type, uint32 *value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; @@ -3839,10 +3840,10 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods return NT_STATUS_INVALID_PARAMETER; } - policy_attr = get_account_policy_attr(policy_index); + policy_attr = get_account_policy_attr(type); if (!policy_attr) { DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid " - "policy index: %d\n", policy_index)); + "policy index: %d\n", type)); return ntstatus; } @@ -3896,17 +3897,18 @@ out: Guenther */ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, - int policy_index, uint32 *value) + enum pdb_policy_type type, + uint32_t *value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; - if (cache_account_policy_get(policy_index, value)) { + if (cache_account_policy_get(type, value)) { DEBUG(11,("ldapsam_get_account_policy: got valid value from " "cache\n")); return NT_STATUS_OK; } - ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index, + ntstatus = ldapsam_get_account_policy_from_ldap(methods, type, value); if (NT_STATUS_IS_OK(ntstatus)) { goto update_cache; @@ -3917,27 +3919,27 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, #if 0 /* should we automagically migrate old tdb value here ? */ - if (account_policy_get(policy_index, value)) + if (account_policy_get(type, value)) goto update_ldap; DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying " - "default\n", policy_index)); + "default\n", type)); #endif - if (!account_policy_get_default(policy_index, value)) { + if (!account_policy_get_default(type, value)) { return ntstatus; } /* update_ldap: */ - ntstatus = ldapsam_set_account_policy(methods, policy_index, *value); + ntstatus = ldapsam_set_account_policy(methods, type, *value); if (!NT_STATUS_IS_OK(ntstatus)) { return ntstatus; } update_cache: - if (!cache_account_policy_set(policy_index, *value)) { + if (!cache_account_policy_set(type, *value)) { DEBUG(0,("ldapsam_get_account_policy: failed to update local " "tdb as a cache\n")); return NT_STATUS_UNSUCCESSFUL; diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index 682c7fe9a5..6fc87efb1d 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -35,7 +35,7 @@ static int netlogon_params_fetch_values(const char *key, struct regval_ctr *regv { uint32 dwValue; - if (!pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue)) { + if (!pdb_get_account_policy(PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, &dwValue)) { dwValue = 0; } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 1085251421..b27603f261 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -639,9 +639,9 @@ NTSTATUS _samr_GetUserPwInfo(pipes_struct *p, switch (sid_type) { case SID_NAME_USER: become_root(); - pdb_get_account_policy(AP_MIN_PASSWORD_LEN, + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &min_password_length); - pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, &password_properties); unbecome_root(); @@ -2079,19 +2079,19 @@ NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p, /* AS ROOT !!! */ - pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp); + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp); dominfo->min_password_length = tmp; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp); dominfo->password_history_length = tmp; - pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, &dominfo->password_properties); - pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp); u_expire = account_policy_temp; - pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp); u_min_age = account_policy_temp; /* !AS ROOT */ @@ -3305,19 +3305,19 @@ static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx, /* AS ROOT !!! */ - pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp); r->min_password_length = account_policy_temp; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp); r->password_history_length = account_policy_temp; - pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, &r->password_properties); - pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp); u_expire = account_policy_temp; - pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp); u_min_age = account_policy_temp; /* !AS ROOT */ @@ -3352,7 +3352,7 @@ static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx, r->num_groups = count_sam_groups(dinfo->disp_info); r->num_aliases = count_sam_aliases(dinfo->disp_info); - pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout); + pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout); unix_to_nt_time_abs(&r->force_logoff_time, u_logout); @@ -3389,7 +3389,7 @@ static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx, { uint32_t ul; - pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul); + pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul); u_logout = (time_t)ul; } @@ -3506,16 +3506,16 @@ static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx, become_root(); - pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp); u_lock_duration = account_policy_temp; if (u_lock_duration != -1) { u_lock_duration *= 60; } - pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp); u_reset_time = account_policy_temp * 60; - pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp); r->lockout_threshold = account_policy_temp; /* !AS ROOT */ @@ -3541,16 +3541,16 @@ static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx, /* AS ROOT !!! */ - pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp); u_lock_duration = account_policy_temp; if (u_lock_duration != -1) { u_lock_duration *= 60; } - pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp); u_reset_time = account_policy_temp * 60; - pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp); r->lockout_threshold = account_policy_temp; /* !AS ROOT */ @@ -6205,9 +6205,9 @@ NTSTATUS _samr_GetDomPwInfo(pipes_struct *p, } become_root(); - pdb_get_account_policy(AP_MIN_PASSWORD_LEN, + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &min_password_length); - pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, &password_properties); unbecome_root(); @@ -6376,14 +6376,14 @@ static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx, u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age); u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age); - pdb_set_account_policy(AP_MIN_PASSWORD_LEN, + pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, (uint32_t)r->min_password_length); - pdb_set_account_policy(AP_PASSWORD_HISTORY, + pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY, (uint32_t)r->password_history_length); - pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, (uint32_t)r->password_properties); - pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire); - pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age); + pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire); + pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age); return NT_STATUS_OK; } @@ -6398,7 +6398,7 @@ static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx, u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time); - pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout); + pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout); return NT_STATUS_OK; } @@ -6418,9 +6418,9 @@ static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx, u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60; - pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration); - pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time); - pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, + pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration); + pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time); + pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, (uint32_t)r->lockout_threshold); return NT_STATUS_OK; diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index 69daa31e9c..1e5988af33 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -619,7 +619,7 @@ void copy_id21_to_sam_passwd(const char *log_prefix, uint32_t pwd_max_age = 0; time_t now = time(NULL); - pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age); + pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &pwd_max_age); if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) { pwd_max_age = get_time_t_max(); diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 2eb09d176d..64f988f1f7 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -1024,7 +1024,7 @@ static bool check_passwd_history(struct samu *sampass, const char *plaintext) int i; uint32 pwHisLen, curr_pwHisLen; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHisLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHisLen); if (pwHisLen == 0) { return False; } @@ -1107,7 +1107,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw * denies machines to change the password. * * Should we deny also SRVTRUST and/or DOMSTRUST ? .SSS. */ if (pdb_get_acct_ctrl(hnd) & ACB_WSTRUST) { - if (pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) { + if (pdb_get_account_policy(PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) { DEBUG(1, ("Machine %s cannot change password now, " "denied by Refuse Machine Password Change policy\n", username)); @@ -1130,7 +1130,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw return NT_STATUS_ACCOUNT_RESTRICTION; } - if (pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) { + if (pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) { DEBUG(1, ("user %s cannot change password - password too short\n", username)); DEBUGADD(1, (" account policy min password len = %d\n", min_len)); diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c index ab7edde85d..950177c3ca 100644 --- a/source3/torture/pdbtest.c +++ b/source3/torture/pdbtest.c @@ -288,7 +288,7 @@ int main(int argc, char **argv) pdb_set_homedir(out, "\\\\torture\\home", PDB_SET); pdb_set_logon_script(out, "torture_script.cmd", PDB_SET); - pdb_get_account_policy(AP_PASSWORD_HISTORY, &history); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &history); if (history * PW_HISTORY_ENTRY_LEN < NT_HASH_LEN) { buf = (uint8 *)TALLOC(ctx, NT_HASH_LEN); } else { @@ -311,8 +311,8 @@ int main(int argc, char **argv) } pdb_set_pw_history(out, buf, history, PDB_SET); - pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire); - pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age); + pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire); + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &min_age); pdb_set_pass_last_set_time(out, time(NULL), PDB_SET); if (expire == 0 || expire == (uint32)-1) { diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c index b18f0ff595..9a43c6d6a2 100644 --- a/source3/winbindd/winbindd_passdb.c +++ b/source3/winbindd/winbindd_passdb.c @@ -332,29 +332,29 @@ static NTSTATUS password_policy(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - if (!pdb_get_account_policy(AP_MIN_PASSWORD_LEN, + if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp)) { return NT_STATUS_ACCESS_DENIED; } p->min_password_length = account_policy_temp; - if (!pdb_get_account_policy(AP_PASSWORD_HISTORY, + if (!pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp)) { return NT_STATUS_ACCESS_DENIED; } p->password_history_length = account_policy_temp; - if (!pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + if (!pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, &p->password_properties)) { return NT_STATUS_ACCESS_DENIED; } - if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp)) { + if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp)) { return NT_STATUS_ACCESS_DENIED; } u_expire = account_policy_temp; - if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp)) { + if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp)) { return NT_STATUS_ACCESS_DENIED; } u_min_age = account_policy_temp; -- cgit From 9d7cb4826a7b605a170bd5d5efee331557188b6e Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 10 Jul 2009 22:44:27 +0200 Subject: remove all '\n' from ldb_debug --- source4/lib/ldb/common/ldb.c | 2 +- source4/lib/ldb/common/ldb_debug.c | 1 + source4/lib/ldb/common/ldb_ldif.c | 12 ++++++------ source4/lib/ldb/common/ldb_match.c | 2 +- source4/lib/ldb/common/ldb_modules.c | 24 ++++++++++++------------ source4/lib/ldb/ldb_ildap/ldb_ildap.c | 6 +++--- source4/lib/ldb/ldb_ldap/ldb_ldap.c | 6 +++--- source4/lib/ldb/ldb_map/ldb_map.c | 16 ++++++++-------- source4/lib/ldb/ldb_map/ldb_map_inbound.c | 8 ++++---- source4/lib/ldb/ldb_map/ldb_map_outbound.c | 8 ++++---- source4/lib/ldb/ldb_tdb/ldb_cache.c | 6 +++--- source4/lib/ldb/ldb_tdb/ldb_index.c | 6 +++--- source4/lib/ldb/ldb_tdb/ldb_pack.c | 2 +- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- source4/lib/ldb/modules/asq.c | 2 +- source4/lib/ldb/modules/operational.c | 4 ++-- source4/lib/ldb/modules/paged_results.c | 2 +- source4/lib/ldb/modules/rdn_name.c | 4 ++-- source4/lib/ldb/modules/sort.c | 2 +- 19 files changed, 58 insertions(+), 57 deletions(-) diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 64ad6832db..164e5a95a0 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -240,7 +240,7 @@ int ldb_connect(struct ldb_context *ldb, const char *url, if (ldb_load_modules(ldb, options) != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_FATAL, - "Unable to load modules for %s: %s\n", + "Unable to load modules for %s: %s", url, ldb_errstring(ldb)); return LDB_ERR_OTHER; } diff --git a/source4/lib/ldb/common/ldb_debug.c b/source4/lib/ldb/common/ldb_debug.c index f8009eb8a3..7680862c2c 100644 --- a/source4/lib/ldb/common/ldb_debug.c +++ b/source4/lib/ldb/common/ldb_debug.c @@ -56,6 +56,7 @@ static void ldb_debug_stderr(void *context, enum ldb_debug_level level, { if (level <= LDB_DEBUG_WARNING) { vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); } } diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c index d64a9f1c3a..d890ff8300 100644 --- a/source4/lib/ldb/common/ldb_ldif.c +++ b/source4/lib/ldb/common/ldb_ldif.c @@ -296,7 +296,7 @@ int ldb_ldif_write(struct ldb_context *ldb, } } if (!ldb_changetypes[i].name) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d\n", + ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d", ldif->changetype); talloc_free(mem_ctx); return -1; @@ -561,7 +561,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, /* first line must be a dn */ if (ldb_attr_cmp(attr, "dn") != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'\n", + ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'", attr); goto failed; } @@ -569,7 +569,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value); if ( ! ldb_dn_validate(msg->dn)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'\n", + ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'", (char *)value.data); goto failed; } @@ -588,8 +588,8 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, } } if (!ldb_changetypes[i].name) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Bad ldif changetype '%s'\n",(char *)value.data); + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Bad ldif changetype '%s'",(char *)value.data); } flags = 0; continue; @@ -638,7 +638,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, } if (value.length == 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Attribute value cannot be empty for attribute '%s'\n", el->name); + "Error: Attribute value cannot be empty for attribute '%s'", el->name); goto failed; } if (value.data != el->values[el->num_values].data) { diff --git a/source4/lib/ldb/common/ldb_match.c b/source4/lib/ldb/common/ldb_match.c index c622701d30..e6ee0de027 100644 --- a/source4/lib/ldb/common/ldb_match.c +++ b/source4/lib/ldb/common/ldb_match.c @@ -335,7 +335,7 @@ static int ldb_match_extended(struct ldb_context *ldb, } } if (comp == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s\n", + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s", tree->u.extended.rule_id); return -1; } diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index ae97ef4cce..05dffd005a 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -84,13 +84,13 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m /* spaces not admitted */ modstr = ldb_modules_strdup_no_spaces(mem_ctx, string); if ( ! modstr) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()\n"); + ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()"); return NULL; } modules = talloc_realloc(mem_ctx, modules, char *, 2); if ( ! modules ) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n"); + ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); talloc_free(modstr); return NULL; } @@ -106,7 +106,7 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m i++; modules = talloc_realloc(mem_ctx, modules, char *, i + 2); if ( ! modules ) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n"); + ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); return NULL; } @@ -239,7 +239,7 @@ int ldb_connect_backend(struct ldb_context *ldb, if (fn == NULL) { ldb_debug(ldb, LDB_DEBUG_FATAL, - "Unable to find backend for '%s'\n", url); + "Unable to find backend for '%s'", url); return LDB_ERR_OTHER; } @@ -247,7 +247,7 @@ int ldb_connect_backend(struct ldb_context *ldb, if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR, - "Failed to connect to '%s'\n", url); + "Failed to connect to '%s'", url); return ret; } return ret; @@ -304,18 +304,18 @@ static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name, path = talloc_asprintf(ldb, "%s/%s.%s", ldb->modules_dir, name, SHLIBEXT); - ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path); + ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s", name, path); handle = dlopen(path, RTLD_NOW); if (handle == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s\n", name, path, dlerror()); + ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s", name, path, dlerror()); return NULL; } sym = (int (*)(void))dlsym(handle, symbol); if (sym == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s\n", symbol, path, dlerror()); + ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s", symbol, path, dlerror()); return NULL; } @@ -351,7 +351,7 @@ int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, str } if (ops == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n", + ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found", module_list[i]); continue; } @@ -382,7 +382,7 @@ int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module) if (module) { int ret = module->ops->init_context(module); if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed\n", module->ops->name); + ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed", module->ops->name); return ret; } } @@ -428,7 +428,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); } else if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb)); + ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out", ldb_errstring(ldb)); talloc_free(mem_ctx); return ret; } else { @@ -436,7 +436,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) if (res->count == 0) { ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); } else if (res->count > 1) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", res->count); + ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out", res->count); talloc_free(mem_ctx); return -1; } else { diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index 4447d0e09a..ffde048223 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -790,7 +790,7 @@ static int ildb_connect(struct ldb_context *ldb, const char *url, status = ldap_connect(ildb->ldap, url); if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s\n", + ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s", url, ldap_errstr(ildb->ldap, module, status)); goto failed; } @@ -810,14 +810,14 @@ static int ildb_connect(struct ldb_context *ldb, const char *url, const char *password = cli_credentials_get_password(creds); status = ldap_bind_simple(ildb->ldap, bind_dn, password); if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n", + ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s", ldap_errstr(ildb->ldap, module, status)); goto failed; } } else { status = ldap_bind_sasl(ildb->ldap, creds, lp_ctx); if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n", + ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s", ldap_errstr(ildb->ldap, module, status)); goto failed; } diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index 43a01f75a7..52c16101bb 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -219,7 +219,7 @@ static int lldb_search(struct lldb_context *lldb_ac) } if (req->controls != NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!\n"); + ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!"); } ldb_request_set_state(req, LDB_ASYNC_PENDING); @@ -871,7 +871,7 @@ static int lldb_connect(struct ldb_context *ldb, ret = ldap_initialize(&lldb->ldap, url); if (ret != LDAP_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s\n", + ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s", url, ldap_err2string(ret)); goto failed; } @@ -880,7 +880,7 @@ static int lldb_connect(struct ldb_context *ldb, ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); if (ret != LDAP_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s\n", + ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s", ldap_err2string(ret)); goto failed; } diff --git a/source4/lib/ldb/ldb_map/ldb_map.c b/source4/lib/ldb/ldb_map/ldb_map.c index 5b4ea7910a..68e9d3f392 100644 --- a/source4/lib/ldb/ldb_map/ldb_map.c +++ b/source4/lib/ldb/ldb_map/ldb_map.c @@ -242,7 +242,7 @@ int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *reque default: ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Invalid remote request!\n"); + "Invalid remote request!"); return LDB_ERR_OPERATIONS_ERROR; } @@ -503,14 +503,14 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct case MAP_GENERATE: ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "MAP_IGNORE/MAP_GENERATE attribute '%s' " - "used in DN!\n", ldb_dn_get_component_name(dn, i)); + "used in DN!", ldb_dn_get_component_name(dn, i)); goto failed; case MAP_CONVERT: if (map->u.convert.convert_local == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "'convert_local' not set for attribute '%s' " - "used in DN!\n", ldb_dn_get_component_name(dn, i)); + "used in DN!", ldb_dn_get_component_name(dn, i)); goto failed; } /* fall through */ @@ -578,14 +578,14 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struc case MAP_GENERATE: ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "MAP_IGNORE/MAP_GENERATE attribute '%s' " - "used in DN!\n", ldb_dn_get_component_name(dn, i)); + "used in DN!", ldb_dn_get_component_name(dn, i)); goto failed; case MAP_CONVERT: if (map->u.convert.convert_remote == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "'convert_remote' not set for attribute '%s' " - "used in DN!\n", ldb_dn_get_component_name(dn, i)); + "used in DN!", ldb_dn_get_component_name(dn, i)); goto failed; } /* fall through */ @@ -1007,7 +1007,7 @@ static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data, dn = ldb_dn_new_fmt(data, ldb, "%s=%s", MAP_DN_NAME, name); if ( ! ldb_dn_validate(dn)) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Failed to construct '%s' DN!\n", MAP_DN_NAME); + "Failed to construct '%s' DN!", MAP_DN_NAME); return LDB_ERR_OPERATIONS_ERROR; } @@ -1018,13 +1018,13 @@ static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data, } if (res->count == 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "No results for '%s=%s'!\n", MAP_DN_NAME, name); + "No results for '%s=%s'!", MAP_DN_NAME, name); talloc_free(res); return LDB_ERR_CONSTRAINT_VIOLATION; } if (res->count > 1) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Too many results for '%s=%s'!\n", MAP_DN_NAME, name); + "Too many results for '%s=%s'!", MAP_DN_NAME, name); talloc_free(res); return LDB_ERR_CONSTRAINT_VIOLATION; } diff --git a/source4/lib/ldb/ldb_map/ldb_map_inbound.c b/source4/lib/ldb/ldb_map/ldb_map_inbound.c index 455740ce59..89037419fb 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_inbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_inbound.c @@ -73,7 +73,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l /* Unknown attribute: ignore */ if (map == NULL) { ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Not mapping attribute '%s': no mapping found\n", + "Not mapping attribute '%s': no mapping found", old->name); goto local; } @@ -86,7 +86,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l if (map->u.convert.convert_local == NULL) { ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " "Not mapping attribute '%s': " - "'convert_local' not set\n", + "'convert_local' not set", map->local_name); goto local; } @@ -100,7 +100,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l if (map->u.generate.generate_remote == NULL) { ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " "Not mapping attribute '%s': " - "'generate_remote' not set\n", + "'generate_remote' not set", map->local_name); goto local; } @@ -167,7 +167,7 @@ static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *loca /* Skip 'IS_MAPPED' */ if (ldb_attr_cmp(msg->elements[i].name, IS_MAPPED) == 0) { ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Skipping attribute '%s'\n", + "Skipping attribute '%s'", msg->elements[i].name); continue; } diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c index ffcefad6be..4487d7e763 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_outbound.c @@ -304,7 +304,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local if (map->u.convert.convert_remote == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "Skipping attribute '%s': " - "'convert_remote' not set\n", + "'convert_remote' not set", attr_name); return LDB_SUCCESS; } @@ -323,7 +323,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local if (map->u.generate.generate_local == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " "Skipping attribute '%s': " - "'generate_local' not set\n", + "'generate_local' not set", attr_name); return LDB_SUCCESS; } @@ -900,7 +900,7 @@ static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, if (map->type == MAP_GENERATE) { ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " "Skipping attribute '%s': " - "'convert_operator' not set\n", + "'convert_operator' not set", tree->u.equality.attr); *new = NULL; return 0; @@ -1062,7 +1062,7 @@ int map_return_entry(struct map_context *ac, struct ldb_reply *ares) ac->req->op.search.scope)) { ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: " "Skipping record '%s': " - "doesn't match original search\n", + "doesn't match original search", ldb_dn_get_linearized(ares->message->dn)); return LDB_SUCCESS; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c index 042c1c9282..2c399686ea 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c @@ -141,7 +141,7 @@ static int ltdb_attributes_load(struct ldb_module *module) const struct ldb_schema_syntax *s; if (ltdb_attributes_flags(&msg->elements[i], &flags) != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'\n", msg->elements[i].name); + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'", msg->elements[i].name); goto failed; } switch (flags & ~LTDB_FLAG_HIDDEN) { @@ -156,7 +156,7 @@ static int ltdb_attributes_load(struct ldb_module *module) break; default: ldb_debug(ldb, LDB_DEBUG_ERROR, - "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES\n", + "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES", flags, msg->elements[i].name); goto failed; } @@ -164,7 +164,7 @@ static int ltdb_attributes_load(struct ldb_module *module) s = ldb_standard_syntax_by_name(ldb, syntax); if (s == NULL) { ldb_debug(ldb, LDB_DEBUG_ERROR, - "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES\n", + "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES", syntax, msg->elements[i].name); goto failed; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index fab60cb125..1daa4500f8 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -1409,7 +1409,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, struct ldb_ldif ldif; ldb_debug(ldb, LDB_DEBUG_ERROR, - "ERROR: dn %s not found in %s\n", dn, + "ERROR: dn %s not found in %s", dn, ldb_dn_get_linearized(dn_key)); ldif.changetype = LDB_CHANGETYPE_NONE; ldif.msg = msg; @@ -1587,7 +1587,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * key2 = ltdb_key(module, msg->dn); if (key2.dptr == NULL) { /* probably a corrupt record ... darn */ - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s\n", + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s", ldb_dn_get_linearized(msg->dn)); talloc_free(msg); return 0; @@ -1609,7 +1609,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements); } else { ldb_debug(ldb, LDB_DEBUG_ERROR, - "Adding special ONE LEVEL index failed (%s)!\n", + "Adding special ONE LEVEL index failed (%s)!", ldb_dn_get_linearized(msg->dn)); } diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c index 1995606f88..5640e7053c 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c @@ -280,7 +280,7 @@ int ltdb_unpack_data(struct ldb_module *module, if (remaining != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: %d bytes unread in ltdb_unpack_data\n", remaining); + "Error: %d bytes unread in ltdb_unpack_data", remaining); } return 0; diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 4a452761b8..d4f7b452cb 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1276,7 +1276,7 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url, ldb_get_create_perms(ldb), ldb); if (!ltdb->tdb) { ldb_debug(ldb, LDB_DEBUG_ERROR, - "Unable to open tdb '%s'\n", path); + "Unable to open tdb '%s'", path); talloc_free(ltdb); return -1; } diff --git a/source4/lib/ldb/modules/asq.c b/source4/lib/ldb/modules/asq.c index dd5afd868c..271cf52625 100644 --- a/source4/lib/ldb/modules/asq.c +++ b/source4/lib/ldb/modules/asq.c @@ -393,7 +393,7 @@ static int asq_init(struct ldb_module *module) ret = ldb_mod_register_control(module, LDB_CONTROL_ASQ_OID); if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!\n"); + ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!"); } return ldb_next_init(module); diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c index 43b223b52e..77b0014afa 100644 --- a/source4/lib/ldb/modules/operational.c +++ b/source4/lib/ldb/modules/operational.c @@ -169,8 +169,8 @@ static int operational_search_post_process(struct ldb_module *module, return 0; failed: - ldb_debug_set(ldb, LDB_DEBUG_WARNING, - "operational_search_post_process failed for attribute '%s'\n", + ldb_debug_set(ldb, LDB_DEBUG_WARNING, + "operational_search_post_process failed for attribute '%s'", attrs[a]); return -1; } diff --git a/source4/lib/ldb/modules/paged_results.c b/source4/lib/ldb/modules/paged_results.c index f2692305d5..b712f84872 100644 --- a/source4/lib/ldb/modules/paged_results.c +++ b/source4/lib/ldb/modules/paged_results.c @@ -409,7 +409,7 @@ static int paged_request_init(struct ldb_module *module) if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_WARNING, "paged_results:" - "Unable to register control with rootdse!\n"); + "Unable to register control with rootdse!"); } return ldb_next_init(module); diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index 880678d89d..e9f873f073 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -98,7 +98,7 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) int i, ret; ldb = ldb_module_get_ctx(module); - ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record\n"); + ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record"); /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.add.message->dn)) { @@ -288,7 +288,7 @@ static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) int ret; ldb = ldb_module_get_ctx(module); - ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename\n"); + ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename"); /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.rename.newdn)) { diff --git a/source4/lib/ldb/modules/sort.c b/source4/lib/ldb/modules/sort.c index a95a86140c..b4ea017b32 100644 --- a/source4/lib/ldb/modules/sort.c +++ b/source4/lib/ldb/modules/sort.c @@ -339,7 +339,7 @@ static int server_sort_init(struct ldb_module *module) if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_WARNING, "server_sort:" - "Unable to register control with rootdse!\n"); + "Unable to register control with rootdse!"); } return ldb_next_init(module); -- cgit From d9c0d5823624d302c6fa635d2e44aab985fd307c Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Tue, 14 Jul 2009 17:40:21 +0200 Subject: s3: don't make same innetgr check twice --- source3/smbd/password.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 928ef0169e..58824b6e23 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -428,16 +428,16 @@ bool user_in_netgroup(struct smbd_server_connection *sconn, if (innetgr(ngname, NULL, user, sconn->smb1.sessions.my_yp_domain)) { DEBUG(5,("user_in_netgroup: Found\n")); return true; - } else { - - /* - * Ok, innetgr is case sensitive. Try once more with lowercase - * just in case. Attempt to fix #703. JRA. - */ + } - fstrcpy(lowercase_user, user); - strlower_m(lowercase_user); + /* + * Ok, innetgr is case sensitive. Try once more with lowercase + * just in case. Attempt to fix #703. JRA. + */ + fstrcpy(lowercase_user, user); + strlower_m(lowercase_user); + if (strcmp(user,lowercase_user) != 0) { DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", lowercase_user, sconn->smb1.sessions.my_yp_domain? @@ -449,6 +449,9 @@ bool user_in_netgroup(struct smbd_server_connection *sconn, DEBUG(5,("user_in_netgroup: Found\n")); return true; } + } else { + /* user name was already lower case! */ + return false; } #endif /* HAVE_NETGROUP */ return false; -- cgit From 99c7ee3c9145b6187113ff29500b55a32320a9bc Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Tue, 14 Jul 2009 17:55:50 +0200 Subject: s3: make d9c0d58236 better readble and reduce indentation --- source3/smbd/password.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 58824b6e23..b1a749736d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -437,22 +437,22 @@ bool user_in_netgroup(struct smbd_server_connection *sconn, fstrcpy(lowercase_user, user); strlower_m(lowercase_user); - if (strcmp(user,lowercase_user) != 0) { - DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", - lowercase_user, - sconn->smb1.sessions.my_yp_domain? - sconn->smb1.sessions.my_yp_domain:"(ANY)", - ngname)); - - if (innetgr(ngname, NULL, lowercase_user, - sconn->smb1.sessions.my_yp_domain)) { - DEBUG(5,("user_in_netgroup: Found\n")); - return true; - } - } else { + if (strcmp(user,lowercase_user) == 0) { /* user name was already lower case! */ return false; } + + DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", + lowercase_user, + sconn->smb1.sessions.my_yp_domain? + sconn->smb1.sessions.my_yp_domain:"(ANY)", + ngname)); + + if (innetgr(ngname, NULL, lowercase_user, + sconn->smb1.sessions.my_yp_domain)) { + DEBUG(5,("user_in_netgroup: Found\n")); + return true; + } #endif /* HAVE_NETGROUP */ return false; } -- cgit From 9ef6af73b319048fc6f3891573f0e10066dffee6 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 15 Jul 2009 15:34:10 +0800 Subject: s3: Make smbd aware of permission change of usershare. Since usershare are relatively volatile and non-previledge users must disconnect from smbd and reconnect to it to make share permission in effect. --- source3/include/proto.h | 7 +++- source3/include/smb.h | 6 +++ source3/param/loadparm.c | 11 +++++ source3/smbd/conn.c | 1 + source3/smbd/notify_inotify.c | 4 +- source3/smbd/process.c | 58 +++++++++++++++++++++++++- source3/smbd/service.c | 80 ++++++++++++++++++++++++++++++++++++ source3/smbd/uid.c | 96 ++++++++++++++++++++++++++++++++----------- 8 files changed, 235 insertions(+), 28 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 0dd1e98c86..d141de44cf 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4296,6 +4296,7 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, char **pp_comment, SEC_DESC **ppsd, bool *pallow_guest); +bool am_usershare(int iService); int load_usershare_service(const char *servicename); int load_usershare_shares(void); void gfree_loadparm(void); @@ -7063,7 +7064,8 @@ void reply_transs2(struct smb_request *req); bool change_to_guest(void); void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid); -bool change_to_user(connection_struct *conn, uint16 vuid); +bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, + bool recheck, NTSTATUS *pstatus); bool change_to_root_user(void); bool become_authenticated_pipe_user(pipes_struct *p); bool unbecome_authenticated_pipe_user(void); @@ -7072,6 +7074,9 @@ void unbecome_root(void); bool become_user(connection_struct *conn, uint16 vuid); bool unbecome_user(void); +#define change_to_user(conn, vuid) \ + change_to_user_force_recheck(conn, vuid, 0, NULL) + /* The following definitions come from smbd/utmp.c */ void sys_utmp_claim(const char *username, const char *hostname, diff --git a/source3/include/smb.h b/source3/include/smb.h index 2e9cf1b54a..44216f856a 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -550,6 +550,7 @@ typedef struct connection_struct { unsigned cnum; /* an index passed over the wire */ struct share_params *params; bool force_user; + bool force_recheck_perm; struct vuid_cache vuid_cache; struct dptr_struct *dirptr; bool printer; @@ -1398,6 +1399,11 @@ struct bitmap { #define FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200 #define FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400 #define FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800 +#define FILE_NOTIFY_CHANGE_FILE_CONTENT \ + (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME \ + | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE \ + | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_EA \ + | FILE_NOTIFY_CHANGE_SECURITY) #define FILE_NOTIFY_CHANGE_NAME \ (FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 7e4371bf0b..7b4e363f1b 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -8726,6 +8726,17 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i return iService; } +/*************************************************************************** +Am I a usershare service? +***************************************************************************/ +bool am_usershare(int iService) +{ + if (iService >= 0) { + return (ServicePtrs[iService]->usershare == USERSHARE_VALID); + } + return false; +} + /*************************************************************************** Checks if a usershare entry has been modified since last load. ***************************************************************************/ diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index af6e0919a4..3ddb4c094f 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -155,6 +155,7 @@ find_again: return NULL; } conn->cnum = i; + conn->force_recheck_perm = false; conn->force_group_gid = (gid_t)-1; bitmap_set(sconn->smb1.tcons.bmap, i); diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c index 26570a2216..b6be69c8fd 100644 --- a/source3/smbd/notify_inotify.c +++ b/source3/smbd/notify_inotify.c @@ -316,7 +316,9 @@ static const struct { {FILE_NOTIFY_CHANGE_LAST_WRITE, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_LAST_ACCESS, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_EA, IN_ATTRIB}, - {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB} + {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB}, + {FILE_NOTIFY_CHANGE_FILE_CONTENT, IN_MODIFY|IN_DELETE|IN_CREATE|IN_DELETE_SELF + |IN_MOVE_SELF|IN_MOVED_FROM|IN_MOVED_TO}, }; static uint32_t inotify_map(struct notify_entry *e) diff --git a/source3/smbd/process.c b/source3/smbd/process.c index b26bc150db..5b8a325d22 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1286,7 +1286,6 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in } } } - /* Does this call need to be run as the connected user? */ if (flags & AS_USER) { @@ -1303,12 +1302,67 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in } return NULL; } - +#ifdef HAVE_INOTIFY + if (conn->force_recheck_perm) { + int old; + int iService = -1; + const char *service = NULL; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + conn->force_recheck_perm = false; + DEBUG(5, ("switch_message: rechecking permission for connection %x\n", + (unsigned int)conn)); + old = SNUM(conn); + service = lp_servicename(old); + conn->read_only = False; + if (lp_snum_ok(old) && am_usershare(old)) { + iService = load_usershare_service(service); + if (iService < 0 || old != iService) { + /* non-exist service */ + DEBUG(5, ("switch_message: deleting connection %x\n", + (unsigned int)conn)); + DEBUG(5, ("snum %d, sname %s\n", + old, service ? service : "NULL")); + delete_share_security(service); + set_current_service(NULL, 0, True); + close_cnum(smbd_server_conn, conn, conn->vuid); + lp_killservice(old); + reply_nterror(req, NT_STATUS_BAD_NETWORK_NAME); + return NULL; + } + + /* + * Don't have to reauthentication here, but + * need to check share permissions..... + * the vuid cache is a problem.. + */ + + if (!change_to_root_user()) { + smb_panic("cann't change to root user!\n"); + } + + if (!change_to_user_force_recheck(conn, session_tag, + True, &status)) { + reply_nterror(req, status); + remove_deferred_open_smb_message(req->mid); + return conn; + } + } + } else { + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + if (!change_to_user_force_recheck(conn, session_tag, + False, &status)) { + reply_nterror(req, status); + remove_deferred_open_smb_message(req->mid); + return conn; + } + } +#else if (!change_to_user(conn,session_tag)) { reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid)); remove_deferred_open_smb_message(req->mid); return conn; } +#endif /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */ diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 0124b2b047..8ae13b14f3 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -630,6 +630,33 @@ static NTSTATUS create_connection_server_info(struct smbd_server_connection *sco return NT_STATUS_ACCESS_DENIED; } +#ifdef HAVE_INOTIFY +static void share_perm_changed(struct sys_notify_context *ctx, + void *ptr, struct notify_event *ev) +{ + connection_struct *conn = talloc_get_type_abort(ptr, connection_struct); + const char *service = NULL; + service = lp_servicename(SNUM(conn)); + if (strequal(ev->path, service)) { + conn->force_recheck_perm = true; + DEBUG(0, ("share_perm_changed: set recheck flag for connection %x\n", + (unsigned int)conn)); + } +} + +struct notify_context { + struct db_context *db_recursive; + struct db_context *db_onelevel; + struct server_id server; + struct messaging_context *messaging_ctx; + struct notify_list *list; + struct notify_array *array; + int seqnum; + struct sys_notify_context *sys_notify_ctx; + TDB_DATA key; +}; +#endif + /**************************************************************************** Make a connection, given the snum to connect to, and the vuser of the @@ -867,11 +894,64 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn, } if ((!conn->printer) && (!conn->ipc)) { +#ifdef HAVE_INOTIFY + struct sys_notify_context *sys_ctx = NULL; + struct notify_entry e; + struct inotify_watch_context *w = NULL; +#endif conn->notify_ctx = notify_init(conn, server_id_self(), smbd_messaging_context(), smbd_event_context(), conn); +#ifdef HAVE_INOTIFY + /* + * here is the start of monitoring share permissions change. + * For usershares, we have to watch on both + * get_dyn_STATDIR()/servicename and get_dyn_STATDIR()/share_info.tdb. + * For shares in smb.conf, we just watch on + * get_dyn_STATDIR()/share_info.tdb + */ + if (!conn->notify_ctx) { + DEBUG(1, ("change notify is not enabled??\n")); + goto nonotify; + } + sys_ctx = conn->notify_ctx->sys_notify_ctx; + if (!sys_ctx) { + DEBUG(1, ("change notify: out of memory!!\n")); + *pstatus = NT_STATUS_NO_MEMORY; + conn_free(sconn, conn); + return NULL; + } + ZERO_STRUCT(e); + if (am_usershare(SNUM(conn))) { + const char *usershare_path = lp_usershare_path(); + /* This is usershare service. */ + e.path = talloc_strdup(conn, usershare_path); + } else { + goto nonotify; + /* watch normal shares' permission? */ + } + if (!e.path) { + DEBUG(1, ("setting up usershare notify: out of memory!\n")); + *pstatus = status; + conn_free(sconn, conn); + return NULL; + } + e.path_len = strlen(e.path); + e.filter = FILE_NOTIFY_CHANGE_FILE_CONTENT; + status = inotify_watch(sys_ctx, &e, share_perm_changed, + (void *)conn, (void *)&w); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(1, ("add inotify for usershare permission failed!\n")); + *pstatus = status; + conn_free(sconn, conn); + return NULL; + } +#endif } +#ifdef HAVE_INOTIFY +nonotify: +#endif /* ROOT Activities: */ /* diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 2ec50cd4d8..8e5a386a2d 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -82,12 +82,17 @@ static void free_conn_server_info_if_unused(connection_struct *conn) static bool check_user_ok(connection_struct *conn, uint16_t vuid, const struct auth_serversupplied_info *server_info, - int snum) + int snum, bool recheck, NTSTATUS *pstatus) { bool valid_vuid = (vuid != UID_FIELD_INVALID); unsigned int i; bool readonly_share; bool admin_user; + struct vuid_cache_entry *ent0; + + if (pstatus) { + *pstatus = NT_STATUS_OK; + } if (valid_vuid) { struct vuid_cache_entry *ent; @@ -96,18 +101,27 @@ static bool check_user_ok(connection_struct *conn, ent = &conn->vuid_cache.array[i]; if (ent->vuid == vuid) { free_conn_server_info_if_unused(conn); - conn->server_info = ent->server_info; - conn->read_only = ent->read_only; - conn->admin_user = ent->admin_user; - return(True); + ent0 = ent; + if (!recheck) { + conn->server_info = ent->server_info; + conn->read_only = ent->read_only; + conn->admin_user = ent->admin_user; + return(True); + } else { + break; + } } } } if (!user_ok_token(server_info->unix_name, pdb_get_domain(server_info->sam_account), - server_info->ptok, snum)) + server_info->ptok, snum)) { + if (pstatus) { + *pstatus = NT_STATUS_ACCESS_DENIED; + } return(False); + } readonly_share = is_share_read_only_for_token( server_info->unix_name, @@ -128,6 +142,9 @@ static bool check_user_ok(connection_struct *conn, if (!share_access_check(server_info->ptok, lp_servicename(snum), readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { + if (pstatus) { + *pstatus = NT_STATUS_ACCESS_DENIED; + } return False; } @@ -137,13 +154,26 @@ static bool check_user_ok(connection_struct *conn, NULL, server_info->ptok, lp_admin_users(snum)); if (valid_vuid) { - struct vuid_cache_entry *ent = - &conn->vuid_cache.array[conn->vuid_cache.next_entry]; + struct vuid_cache_entry *ent = NULL; + + if (!recheck || i == VUID_CACHE_SIZE) { + /* find a new entry and fill it. */ + ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry]; - conn->vuid_cache.next_entry = - (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; + conn->vuid_cache.next_entry = + (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; - TALLOC_FREE(ent->server_info); + TALLOC_FREE(ent->server_info); + } else if (recheck && (i < VUID_CACHE_SIZE) && (ent0->vuid == vuid)) { + /* she perform forced recheck, replace the old one. */ + ent = ent0; + } else { + /* must not happen */ + DEBUG(0, ("check_user_ok: recheck %s\n", recheck ? "true" : "false")); + DEBUG(0, ("check_user_ok: vuid cache %d -- %d\n", i, VUID_CACHE_SIZE)); + DEBUG(0, ("check_user_ok: vuid %d -- %d\n", ent0->vuid, vuid)); + smb_panic("should not happen"); + } /* * If force_user was set, all server_info's are based on the same @@ -155,6 +185,9 @@ static bool check_user_ok(connection_struct *conn, if (ent->server_info == NULL) { ent->vuid = UID_FIELD_INVALID; + if (pstatus) { + *pstatus = NT_STATUS_NO_MEMORY; + } return false; } @@ -221,7 +254,8 @@ void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid) stack, but modify the current_user entries. ****************************************************************************/ -bool change_to_user(connection_struct *conn, uint16 vuid) +bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, + bool recheck, NTSTATUS *pstatus) { const struct auth_serversupplied_info *server_info = NULL; struct smbd_server_connection *sconn = smbd_server_conn; @@ -235,6 +269,9 @@ bool change_to_user(connection_struct *conn, uint16 vuid) if (!conn) { DEBUG(2,("change_to_user: Connection not open\n")); + if (pstatus) { + *pstatus = NT_STATUS_INVALID_HANDLE; + } return(False); } @@ -245,17 +282,19 @@ bool change_to_user(connection_struct *conn, uint16 vuid) * SMB's - this hurts performance - Badly. */ - if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && - (current_user.ut.uid == conn->server_info->utok.uid)) { - DEBUG(4,("change_to_user: Skipping user change - already " - "user\n")); - return(True); - } else if ((current_user.conn == conn) && - (vuser != NULL) && (current_user.vuid == vuid) && - (current_user.ut.uid == vuser->server_info->utok.uid)) { - DEBUG(4,("change_to_user: Skipping user change - already " - "user\n")); - return(True); + if (!recheck) { + if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && + (current_user.ut.uid == conn->server_info->utok.uid)) { + DEBUG(4,("change_to_user: Skipping user change - already " + "user\n")); + return(True); + } else if ((current_user.conn == conn) && + (vuser != NULL) && (current_user.vuid == vuid) && + (current_user.ut.uid == vuser->server_info->utok.uid)) { + DEBUG(4,("change_to_user: Skipping user change - already " + "user\n")); + return(True); + } } snum = SNUM(conn); @@ -266,10 +305,13 @@ bool change_to_user(connection_struct *conn, uint16 vuid) /* Invalid vuid sent - even with security = share. */ DEBUG(2,("change_to_user: Invalid vuid %d used on " "share %s.\n",vuid, lp_servicename(snum) )); + if (pstatus) { + *pstatus = NT_STATUS_ACCESS_VIOLATION; + } return false; } - if (!check_user_ok(conn, vuid, server_info, snum)) { + if (!check_user_ok(conn, vuid, server_info, snum, recheck, pstatus)) { DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) " "not permitted access to share %s.\n", server_info->sanitized_username, @@ -296,6 +338,9 @@ bool change_to_user(connection_struct *conn, uint16 vuid) } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " "share %s.\n",vuid, lp_servicename(snum) )); + if (pstatus) { + *pstatus = NT_STATUS_DOS(ERRSRV, ERRbaduid); + } return False; } @@ -353,6 +398,9 @@ bool change_to_user(connection_struct *conn, uint16 vuid) DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); + if (pstatus) { + *pstatus = NT_STATUS_OK; + } return(True); } -- cgit From 86865365ce487a8943370ea2f313000a6440ea9a Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 15 Jul 2009 15:36:02 +0800 Subject: S3: Small fix to get rid of annoying log message. Signed-off-by: Bo Yang --- source3/param/loadparm.c | 3 +++ source3/rpc_server/srv_srvsvc_nt.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 7b4e363f1b..4415804a2d 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -5142,6 +5142,9 @@ static char *lp_string(const char *s) #if 0 DEBUG(10, ("lp_string(%s)\n", s)); #endif + if (!s) { + return NULL; + } ret = talloc_sub_basic(ctx, get_current_username(), diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 44acf4d647..c58c08ecdc 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -540,11 +540,13 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, if (lp_browseable(snum) && lp_snum_ok(snum) && is_enumeration_allowed(p, snum) && (all_shares || !is_hidden_share(snum)) ) { - DEBUG(10, ("counting service %s\n", lp_servicename(snum))); + DEBUG(10, ("counting service %s\n", + lp_servicename(snum) ? lp_servicename(snum) : "(null)")); allowed[snum] = true; num_entries++; } else { - DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum))); + DEBUG(10, ("NOT counting service %s\n", + lp_servicename(snum) ? lp_servicename(snum) : "(null)")); } } -- cgit From 2821f5abf5d60cf420877e92db5c615c83471e95 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 15 Jul 2009 15:37:04 +0800 Subject: s3: Fix double free in net usershare. Signed-off-by: Bo Yang --- source3/utils/net_usershare.c | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/source3/utils/net_usershare.c b/source3/utils/net_usershare.c index 992a03d813..d82d30bc2d 100644 --- a/source3/utils/net_usershare.c +++ b/source3/utils/net_usershare.c @@ -163,7 +163,7 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar d_fprintf(stderr, "net usershare delete: share name %s contains " "invalid characters (any of %s)\n", sharename, INVALID_SHARENAME_CHARS); - SAFE_FREE(sharename); + TALLOC_FREE(sharename); return -1; } @@ -172,7 +172,7 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar lp_usershare_path(), sharename); if (!us_path) { - SAFE_FREE(sharename); + TALLOC_FREE(sharename); return -1; } @@ -180,10 +180,10 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar d_fprintf(stderr, "net usershare delete: unable to remove usershare %s. " "Error was %s\n", us_path, strerror(errno)); - SAFE_FREE(sharename); + TALLOC_FREE(sharename); return -1; } - SAFE_FREE(sharename); + TALLOC_FREE(sharename); return 0; } @@ -672,7 +672,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: maximum number of allowed usershares (%d) reached\n", lp_usershare_max_shares() ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -681,7 +680,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) "invalid characters (any of %s)\n", sharename, INVALID_SHARENAME_CHARS); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -690,7 +688,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: share name %s is already a valid system user name\n", sharename ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -698,7 +695,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) full_path = get_basepath(ctx); if (!full_path) { TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } full_path_tmp = talloc_asprintf(ctx, @@ -706,7 +702,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) full_path); if (!full_path_tmp) { TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -715,7 +710,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) sharename); if (!full_path) { TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -724,7 +718,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr,"net usershare add: path %s is not an absolute path.\n", us_path); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -734,7 +727,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) "this is a directory. Error was %s\n", us_path, strerror(errno) ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -742,7 +734,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: path %s is not a directory.\n", us_path ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -756,7 +747,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) "\tto the [global] section of the smb.conf to allow this.\n", us_path ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -786,7 +776,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: malformed acl %s (missing ':').\n", pacl ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -802,7 +791,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) "(access control must be 'r', 'f', or 'd')\n", pacl ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -810,7 +798,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: malformed terminating character for acl %s\n", pacl ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -818,7 +805,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) if ((name = talloc_strndup(ctx, pacl, pcolon - pacl)) == NULL) { d_fprintf(stderr, "talloc_strndup failed\n"); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } if (!string_to_sid(&sid, name)) { @@ -833,7 +819,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "\n"); } TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } } @@ -854,7 +839,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) "but the \"usershare allow guests\" parameter is not enabled " "by this server.\n"); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -865,7 +849,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: cannot create tmp file %s\n", full_path_tmp ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -874,7 +857,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: cannot lstat tmp file %s\n", full_path_tmp ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -883,7 +865,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: cannot fstat tmp file %s\n", full_path_tmp ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -891,7 +872,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: tmp file %s is not a regular file ?\n", full_path_tmp ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -899,7 +879,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: failed to fchmod tmp file %s to 0644n", full_path_tmp ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -915,7 +894,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) (unsigned int)to_write, full_path_tmp, strerror(errno)); unlink(full_path_tmp); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -926,7 +904,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) sharename, strerror(errno)); TALLOC_FREE(ctx); close(tmpfd); - SAFE_FREE(sharename); return -1; } @@ -939,7 +916,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) net_usershare_info(c, 1, my_argv); } - SAFE_FREE(sharename); TALLOC_FREE(ctx); return 0; } -- cgit From 73e96935c3604d21552ba93dfd561eaf7606f52d Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 15 Jul 2009 17:03:04 +0800 Subject: s3: fix build of pdbedit and net_sam. Guenther, please check. Signed-off-by: Bo Yang --- source3/utils/net_sam.c | 8 ++++---- source3/utils/pdbedit.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c index 62abef000d..41daa4180d 100644 --- a/source3/utils/net_sam.c +++ b/source3/utils/net_sam.c @@ -452,7 +452,7 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv const char *account_policy = NULL; uint32 value = 0; uint32 old_value = 0; - int field; + enum pdb_policy_type field; char *endptr; if (argc != 2 || c->display_usage) { @@ -462,7 +462,7 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv } account_policy = argv[0]; - field = account_policy_name_to_fieldnum(account_policy); + field = account_policy_name_to_typenum(account_policy); if (strequal(argv[1], "forever") || strequal(argv[1], "never") || strequal(argv[1], "off")) { @@ -519,7 +519,7 @@ static int net_sam_policy_show(struct net_context *c, int argc, const char **arg { const char *account_policy = NULL; uint32 old_value; - int field; + enum pdb_policy_type field; if (argc != 1 || c->display_usage) { d_fprintf(stderr, "usage: net sam policy show" @@ -528,7 +528,7 @@ static int net_sam_policy_show(struct net_context *c, int argc, const char **arg } account_policy = argv[0]; - field = account_policy_name_to_fieldnum(account_policy); + field = account_policy_name_to_typenum(account_policy); if (field == 0) { const char **names; diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index a464299438..dce2f05a83 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -1109,7 +1109,7 @@ int main (int argc, char **argv) /* account policy operations */ if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) { uint32 value; - int field = account_policy_name_to_fieldnum(account_policy); + enum pdb_policy_type field = account_policy_name_to_typenum(account_policy); if (field == 0) { const char **names; int count; -- cgit From d57e67f9eb5a6a05f0e173d48e86dd1fe050635e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Jul 2009 11:25:45 -0700 Subject: Revert this commit : s3: Make smbd aware of permission change of usershare. Since usershare are relatively volatile and non-previledge users must disconnect from smbd and reconnect to it to make share permission in effect. For now. This is a feature request and I think we need to design it a little differently so as not to touch core change_to_user() code. Jeremy. --- source3/include/proto.h | 7 +--- source3/include/smb.h | 6 --- source3/param/loadparm.c | 11 +++++ source3/smbd/conn.c | 1 - source3/smbd/notify_inotify.c | 4 +- source3/smbd/process.c | 58 +------------------------- source3/smbd/service.c | 80 ------------------------------------ source3/smbd/uid.c | 96 +++++++++++-------------------------------- 8 files changed, 39 insertions(+), 224 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index d141de44cf..0dd1e98c86 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4296,7 +4296,6 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, char **pp_comment, SEC_DESC **ppsd, bool *pallow_guest); -bool am_usershare(int iService); int load_usershare_service(const char *servicename); int load_usershare_shares(void); void gfree_loadparm(void); @@ -7064,8 +7063,7 @@ void reply_transs2(struct smb_request *req); bool change_to_guest(void); void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid); -bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, - bool recheck, NTSTATUS *pstatus); +bool change_to_user(connection_struct *conn, uint16 vuid); bool change_to_root_user(void); bool become_authenticated_pipe_user(pipes_struct *p); bool unbecome_authenticated_pipe_user(void); @@ -7074,9 +7072,6 @@ void unbecome_root(void); bool become_user(connection_struct *conn, uint16 vuid); bool unbecome_user(void); -#define change_to_user(conn, vuid) \ - change_to_user_force_recheck(conn, vuid, 0, NULL) - /* The following definitions come from smbd/utmp.c */ void sys_utmp_claim(const char *username, const char *hostname, diff --git a/source3/include/smb.h b/source3/include/smb.h index 44216f856a..2e9cf1b54a 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -550,7 +550,6 @@ typedef struct connection_struct { unsigned cnum; /* an index passed over the wire */ struct share_params *params; bool force_user; - bool force_recheck_perm; struct vuid_cache vuid_cache; struct dptr_struct *dirptr; bool printer; @@ -1399,11 +1398,6 @@ struct bitmap { #define FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200 #define FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400 #define FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800 -#define FILE_NOTIFY_CHANGE_FILE_CONTENT \ - (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME \ - | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE \ - | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_EA \ - | FILE_NOTIFY_CHANGE_SECURITY) #define FILE_NOTIFY_CHANGE_NAME \ (FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 4415804a2d..5d3ac9207e 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -8740,6 +8740,17 @@ bool am_usershare(int iService) return false; } +/*************************************************************************** +Am I a usershare service? +***************************************************************************/ +bool am_usershare(int iService) +{ + if (iService >= 0) { + return (ServicePtrs[iService]->usershare == USERSHARE_VALID); + } + return false; +} + /*************************************************************************** Checks if a usershare entry has been modified since last load. ***************************************************************************/ diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 3ddb4c094f..af6e0919a4 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -155,7 +155,6 @@ find_again: return NULL; } conn->cnum = i; - conn->force_recheck_perm = false; conn->force_group_gid = (gid_t)-1; bitmap_set(sconn->smb1.tcons.bmap, i); diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c index b6be69c8fd..26570a2216 100644 --- a/source3/smbd/notify_inotify.c +++ b/source3/smbd/notify_inotify.c @@ -316,9 +316,7 @@ static const struct { {FILE_NOTIFY_CHANGE_LAST_WRITE, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_LAST_ACCESS, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_EA, IN_ATTRIB}, - {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB}, - {FILE_NOTIFY_CHANGE_FILE_CONTENT, IN_MODIFY|IN_DELETE|IN_CREATE|IN_DELETE_SELF - |IN_MOVE_SELF|IN_MOVED_FROM|IN_MOVED_TO}, + {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB} }; static uint32_t inotify_map(struct notify_entry *e) diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 5b8a325d22..b26bc150db 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1286,6 +1286,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in } } } + /* Does this call need to be run as the connected user? */ if (flags & AS_USER) { @@ -1302,67 +1303,12 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in } return NULL; } -#ifdef HAVE_INOTIFY - if (conn->force_recheck_perm) { - int old; - int iService = -1; - const char *service = NULL; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - conn->force_recheck_perm = false; - DEBUG(5, ("switch_message: rechecking permission for connection %x\n", - (unsigned int)conn)); - old = SNUM(conn); - service = lp_servicename(old); - conn->read_only = False; - if (lp_snum_ok(old) && am_usershare(old)) { - iService = load_usershare_service(service); - if (iService < 0 || old != iService) { - /* non-exist service */ - DEBUG(5, ("switch_message: deleting connection %x\n", - (unsigned int)conn)); - DEBUG(5, ("snum %d, sname %s\n", - old, service ? service : "NULL")); - delete_share_security(service); - set_current_service(NULL, 0, True); - close_cnum(smbd_server_conn, conn, conn->vuid); - lp_killservice(old); - reply_nterror(req, NT_STATUS_BAD_NETWORK_NAME); - return NULL; - } - - /* - * Don't have to reauthentication here, but - * need to check share permissions..... - * the vuid cache is a problem.. - */ - - if (!change_to_root_user()) { - smb_panic("cann't change to root user!\n"); - } - - if (!change_to_user_force_recheck(conn, session_tag, - True, &status)) { - reply_nterror(req, status); - remove_deferred_open_smb_message(req->mid); - return conn; - } - } - } else { - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - if (!change_to_user_force_recheck(conn, session_tag, - False, &status)) { - reply_nterror(req, status); - remove_deferred_open_smb_message(req->mid); - return conn; - } - } -#else + if (!change_to_user(conn,session_tag)) { reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid)); remove_deferred_open_smb_message(req->mid); return conn; } -#endif /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */ diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 8ae13b14f3..0124b2b047 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -630,33 +630,6 @@ static NTSTATUS create_connection_server_info(struct smbd_server_connection *sco return NT_STATUS_ACCESS_DENIED; } -#ifdef HAVE_INOTIFY -static void share_perm_changed(struct sys_notify_context *ctx, - void *ptr, struct notify_event *ev) -{ - connection_struct *conn = talloc_get_type_abort(ptr, connection_struct); - const char *service = NULL; - service = lp_servicename(SNUM(conn)); - if (strequal(ev->path, service)) { - conn->force_recheck_perm = true; - DEBUG(0, ("share_perm_changed: set recheck flag for connection %x\n", - (unsigned int)conn)); - } -} - -struct notify_context { - struct db_context *db_recursive; - struct db_context *db_onelevel; - struct server_id server; - struct messaging_context *messaging_ctx; - struct notify_list *list; - struct notify_array *array; - int seqnum; - struct sys_notify_context *sys_notify_ctx; - TDB_DATA key; -}; -#endif - /**************************************************************************** Make a connection, given the snum to connect to, and the vuser of the @@ -894,64 +867,11 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn, } if ((!conn->printer) && (!conn->ipc)) { -#ifdef HAVE_INOTIFY - struct sys_notify_context *sys_ctx = NULL; - struct notify_entry e; - struct inotify_watch_context *w = NULL; -#endif conn->notify_ctx = notify_init(conn, server_id_self(), smbd_messaging_context(), smbd_event_context(), conn); -#ifdef HAVE_INOTIFY - /* - * here is the start of monitoring share permissions change. - * For usershares, we have to watch on both - * get_dyn_STATDIR()/servicename and get_dyn_STATDIR()/share_info.tdb. - * For shares in smb.conf, we just watch on - * get_dyn_STATDIR()/share_info.tdb - */ - if (!conn->notify_ctx) { - DEBUG(1, ("change notify is not enabled??\n")); - goto nonotify; - } - sys_ctx = conn->notify_ctx->sys_notify_ctx; - if (!sys_ctx) { - DEBUG(1, ("change notify: out of memory!!\n")); - *pstatus = NT_STATUS_NO_MEMORY; - conn_free(sconn, conn); - return NULL; - } - ZERO_STRUCT(e); - if (am_usershare(SNUM(conn))) { - const char *usershare_path = lp_usershare_path(); - /* This is usershare service. */ - e.path = talloc_strdup(conn, usershare_path); - } else { - goto nonotify; - /* watch normal shares' permission? */ - } - if (!e.path) { - DEBUG(1, ("setting up usershare notify: out of memory!\n")); - *pstatus = status; - conn_free(sconn, conn); - return NULL; - } - e.path_len = strlen(e.path); - e.filter = FILE_NOTIFY_CHANGE_FILE_CONTENT; - status = inotify_watch(sys_ctx, &e, share_perm_changed, - (void *)conn, (void *)&w); - if (NT_STATUS_IS_ERR(status)) { - DEBUG(1, ("add inotify for usershare permission failed!\n")); - *pstatus = status; - conn_free(sconn, conn); - return NULL; - } -#endif } -#ifdef HAVE_INOTIFY -nonotify: -#endif /* ROOT Activities: */ /* diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 8e5a386a2d..2ec50cd4d8 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -82,17 +82,12 @@ static void free_conn_server_info_if_unused(connection_struct *conn) static bool check_user_ok(connection_struct *conn, uint16_t vuid, const struct auth_serversupplied_info *server_info, - int snum, bool recheck, NTSTATUS *pstatus) + int snum) { bool valid_vuid = (vuid != UID_FIELD_INVALID); unsigned int i; bool readonly_share; bool admin_user; - struct vuid_cache_entry *ent0; - - if (pstatus) { - *pstatus = NT_STATUS_OK; - } if (valid_vuid) { struct vuid_cache_entry *ent; @@ -101,27 +96,18 @@ static bool check_user_ok(connection_struct *conn, ent = &conn->vuid_cache.array[i]; if (ent->vuid == vuid) { free_conn_server_info_if_unused(conn); - ent0 = ent; - if (!recheck) { - conn->server_info = ent->server_info; - conn->read_only = ent->read_only; - conn->admin_user = ent->admin_user; - return(True); - } else { - break; - } + conn->server_info = ent->server_info; + conn->read_only = ent->read_only; + conn->admin_user = ent->admin_user; + return(True); } } } if (!user_ok_token(server_info->unix_name, pdb_get_domain(server_info->sam_account), - server_info->ptok, snum)) { - if (pstatus) { - *pstatus = NT_STATUS_ACCESS_DENIED; - } + server_info->ptok, snum)) return(False); - } readonly_share = is_share_read_only_for_token( server_info->unix_name, @@ -142,9 +128,6 @@ static bool check_user_ok(connection_struct *conn, if (!share_access_check(server_info->ptok, lp_servicename(snum), readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { - if (pstatus) { - *pstatus = NT_STATUS_ACCESS_DENIED; - } return False; } @@ -154,26 +137,13 @@ static bool check_user_ok(connection_struct *conn, NULL, server_info->ptok, lp_admin_users(snum)); if (valid_vuid) { - struct vuid_cache_entry *ent = NULL; - - if (!recheck || i == VUID_CACHE_SIZE) { - /* find a new entry and fill it. */ - ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry]; + struct vuid_cache_entry *ent = + &conn->vuid_cache.array[conn->vuid_cache.next_entry]; - conn->vuid_cache.next_entry = - (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; + conn->vuid_cache.next_entry = + (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; - TALLOC_FREE(ent->server_info); - } else if (recheck && (i < VUID_CACHE_SIZE) && (ent0->vuid == vuid)) { - /* she perform forced recheck, replace the old one. */ - ent = ent0; - } else { - /* must not happen */ - DEBUG(0, ("check_user_ok: recheck %s\n", recheck ? "true" : "false")); - DEBUG(0, ("check_user_ok: vuid cache %d -- %d\n", i, VUID_CACHE_SIZE)); - DEBUG(0, ("check_user_ok: vuid %d -- %d\n", ent0->vuid, vuid)); - smb_panic("should not happen"); - } + TALLOC_FREE(ent->server_info); /* * If force_user was set, all server_info's are based on the same @@ -185,9 +155,6 @@ static bool check_user_ok(connection_struct *conn, if (ent->server_info == NULL) { ent->vuid = UID_FIELD_INVALID; - if (pstatus) { - *pstatus = NT_STATUS_NO_MEMORY; - } return false; } @@ -254,8 +221,7 @@ void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid) stack, but modify the current_user entries. ****************************************************************************/ -bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, - bool recheck, NTSTATUS *pstatus) +bool change_to_user(connection_struct *conn, uint16 vuid) { const struct auth_serversupplied_info *server_info = NULL; struct smbd_server_connection *sconn = smbd_server_conn; @@ -269,9 +235,6 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, if (!conn) { DEBUG(2,("change_to_user: Connection not open\n")); - if (pstatus) { - *pstatus = NT_STATUS_INVALID_HANDLE; - } return(False); } @@ -282,19 +245,17 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, * SMB's - this hurts performance - Badly. */ - if (!recheck) { - if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && - (current_user.ut.uid == conn->server_info->utok.uid)) { - DEBUG(4,("change_to_user: Skipping user change - already " - "user\n")); - return(True); - } else if ((current_user.conn == conn) && - (vuser != NULL) && (current_user.vuid == vuid) && - (current_user.ut.uid == vuser->server_info->utok.uid)) { - DEBUG(4,("change_to_user: Skipping user change - already " - "user\n")); - return(True); - } + if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && + (current_user.ut.uid == conn->server_info->utok.uid)) { + DEBUG(4,("change_to_user: Skipping user change - already " + "user\n")); + return(True); + } else if ((current_user.conn == conn) && + (vuser != NULL) && (current_user.vuid == vuid) && + (current_user.ut.uid == vuser->server_info->utok.uid)) { + DEBUG(4,("change_to_user: Skipping user change - already " + "user\n")); + return(True); } snum = SNUM(conn); @@ -305,13 +266,10 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, /* Invalid vuid sent - even with security = share. */ DEBUG(2,("change_to_user: Invalid vuid %d used on " "share %s.\n",vuid, lp_servicename(snum) )); - if (pstatus) { - *pstatus = NT_STATUS_ACCESS_VIOLATION; - } return false; } - if (!check_user_ok(conn, vuid, server_info, snum, recheck, pstatus)) { + if (!check_user_ok(conn, vuid, server_info, snum)) { DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) " "not permitted access to share %s.\n", server_info->sanitized_username, @@ -338,9 +296,6 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " "share %s.\n",vuid, lp_servicename(snum) )); - if (pstatus) { - *pstatus = NT_STATUS_DOS(ERRSRV, ERRbaduid); - } return False; } @@ -398,9 +353,6 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); - if (pstatus) { - *pstatus = NT_STATUS_OK; - } return(True); } -- cgit From 74046c8054d2afe7da51c1ff09ffd594a9cb8b73 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 18:33:01 +0200 Subject: TALLOC_FREE(sd) in check_open_rights upon an error --- source3/smbd/open.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index e01350f2bf..404461fb5e 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -94,6 +94,7 @@ static NTSTATUS check_open_rights(struct connection_struct *conn, "on %s: %s\n", smb_fname_str_dbg(smb_fname), nt_errstr(status))); + TALLOC_FREE(sd); return status; } -- cgit From 72da71acf925ffe4cc87ca2bcba3770af3fe3d8b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 18:34:07 +0200 Subject: Create a correct talloc hierarchy in make_sec_acl() --- libcli/security/secacl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcli/security/secacl.c b/libcli/security/secacl.c index 9373ef5812..29afe460b1 100644 --- a/libcli/security/secacl.c +++ b/libcli/security/secacl.c @@ -51,7 +51,7 @@ struct security_acl *make_sec_acl(TALLOC_CTX *ctx, positive number. */ if ((num_aces) && - ((dst->aces = talloc_array(ctx, struct security_ace, num_aces)) + ((dst->aces = talloc_array(dst, struct security_ace, num_aces)) == NULL)) { return NULL; } -- cgit From 749a50874906ba38f1085065933f2781b81d5dfa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 18:34:36 +0200 Subject: Create a talloc_stackframe for each file in wildcard unlink There might be *many* files to delete --- source3/smbd/reply.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index e35c5bc6d6..4d0a2b8c97 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2646,18 +2646,23 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, while ((dname = ReadDirName(dir_hnd, &offset, &smb_fname->st))) { + TALLOC_CTX *frame = talloc_stackframe(); + if (!is_visible_file(conn, fname_dir, dname, &smb_fname->st, true)) { + TALLOC_FREE(frame); continue; } /* Quick check for "." and ".." */ if (ISDOT(dname) || ISDOTDOT(dname)) { + TALLOC_FREE(frame); continue; } if(!mask_match(dname, fname_mask, conn->case_sensitive)) { + TALLOC_FREE(frame); continue; } @@ -2669,23 +2674,28 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, if (!smb_fname->base_name) { TALLOC_FREE(dir_hnd); status = NT_STATUS_NO_MEMORY; + TALLOC_FREE(frame); goto out; } status = check_name(conn, smb_fname->base_name); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(dir_hnd); + TALLOC_FREE(frame); goto out; } status = do_unlink(conn, req, smb_fname, dirtype); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); continue; } count++; DEBUG(3,("unlink_internals: successful unlink [%s]\n", smb_fname->base_name)); + + TALLOC_FREE(frame); } TALLOC_FREE(dir_hnd); } -- cgit From b134d4bc4ad665b82438eb8e1b5cbd1098a36aed Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 21:28:13 +0200 Subject: Attempt to fix the build --- source3/param/loadparm.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 5d3ac9207e..dbbd6e327d 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -8729,28 +8729,6 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i return iService; } -/*************************************************************************** -Am I a usershare service? -***************************************************************************/ -bool am_usershare(int iService) -{ - if (iService >= 0) { - return (ServicePtrs[iService]->usershare == USERSHARE_VALID); - } - return false; -} - -/*************************************************************************** -Am I a usershare service? -***************************************************************************/ -bool am_usershare(int iService) -{ - if (iService >= 0) { - return (ServicePtrs[iService]->usershare == USERSHARE_VALID); - } - return false; -} - /*************************************************************************** Checks if a usershare entry has been modified since last load. ***************************************************************************/ -- cgit From 036bad61317bc71f59db0e766881dd880253bb52 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Tue, 14 Jul 2009 22:23:39 +0200 Subject: s3: allow setting the TCP_QUICKACK socket option --- source3/lib/util_sock.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 31261afd72..af64f370ba 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -348,6 +348,9 @@ static const smb_socket_option socket_options[] = { #endif #ifdef TCP_FASTACK {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT}, +#endif +#ifdef TCP_QUICKACK + {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK, 0, OPT_BOOL}, #endif {NULL,0,0,0,0}}; -- cgit From b0cce950ba32be3e2a9f10bf4ee6ba34f6da9c12 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 14 Jul 2009 14:33:08 +0200 Subject: s4-smbtorture: restructure test_OpenPrinter_server in RPC-SPOOLSS a bit. Guenther --- source4/torture/rpc/spoolss.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index 10e18e1531..3cfe020892 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -75,20 +75,22 @@ struct test_spoolss_context { #define COMPARE_STRING_ARRAY(tctx, c,r,e) -static bool test_OpenPrinter_server(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx) +static bool test_OpenPrinter_server(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *server_handle) { NTSTATUS status; struct spoolss_OpenPrinter op; - op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)); + op.in.printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); op.in.datatype = NULL; op.in.devmode_ctr.devmode= NULL; op.in.access_mask = 0; - op.out.handle = &ctx->server_handle; + op.out.handle = server_handle; torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername); - status = dcerpc_spoolss_OpenPrinter(p, ctx, &op); + status = dcerpc_spoolss_OpenPrinter(p, tctx, &op); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_OpenPrinter failed"); torture_assert_werr_ok(tctx, op.out.result, "dcerpc_spoolss_OpenPrinter failed"); @@ -2087,7 +2089,7 @@ bool torture_rpc_spoolss(struct torture_context *torture) ctx = talloc_zero(torture, struct test_spoolss_context); - ret &= test_OpenPrinter_server(torture, p, ctx); + ret &= test_OpenPrinter_server(torture, p, &ctx->server_handle); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "W3SvcInstalled"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "BeepEnabled"); -- cgit From 3a367ab10d3da2d9f5261769af06442550a0f029 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 2 Jul 2009 19:38:12 +0200 Subject: s4-smbtorture: add some tests to check spoolss_SetPrinter behavior. Guenther --- source4/torture/rpc/spoolss.c | 558 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 558 insertions(+) diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index 3cfe020892..b6ad1a77c2 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -812,6 +812,564 @@ static bool test_GetPrinter(struct torture_context *tctx, return true; } +static bool test_SetPrinter_errors(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *handle) +{ + struct spoolss_SetPrinter r; + uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + int i; + + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + + info_ctr.level = 0; + info_ctr.info.info0 = NULL; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + + r.in.handle = handle; + r.in.info_ctr = &info_ctr; + r.in.devmode_ctr = &devmode_ctr; + r.in.secdesc_ctr = &secdesc_ctr; + r.in.command = 0; + + torture_comment(tctx, "Testing SetPrinter all zero\n"); + + torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter(p, tctx, &r), + "failed to call SetPrinter"); + torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM, + "failed to call SetPrinter"); + + again: + for (i=0; i < ARRAY_SIZE(levels); i++) { + + struct spoolss_SetPrinterInfo0 info0; + struct spoolss_SetPrinterInfo1 info1; + struct spoolss_SetPrinterInfo2 info2; + struct spoolss_SetPrinterInfo3 info3; + struct spoolss_SetPrinterInfo4 info4; + struct spoolss_SetPrinterInfo5 info5; + struct spoolss_SetPrinterInfo6 info6; + struct spoolss_SetPrinterInfo7 info7; + struct spoolss_DeviceModeInfo info8; + struct spoolss_DeviceModeInfo info9; + + + info_ctr.level = levels[i]; + switch (levels[i]) { + case 0: + ZERO_STRUCT(info0); + info_ctr.info.info0 = &info0; + break; + case 1: + ZERO_STRUCT(info1); + info_ctr.info.info1 = &info1; + break; + case 2: + ZERO_STRUCT(info2); + info_ctr.info.info2 = &info2; + break; + case 3: + ZERO_STRUCT(info3); + info_ctr.info.info3 = &info3; + break; + case 4: + ZERO_STRUCT(info4); + info_ctr.info.info4 = &info4; + break; + case 5: + ZERO_STRUCT(info5); + info_ctr.info.info5 = &info5; + break; + case 6: + ZERO_STRUCT(info6); + info_ctr.info.info6 = &info6; + break; + case 7: + ZERO_STRUCT(info7); + info_ctr.info.info7 = &info7; + break; + case 8: + ZERO_STRUCT(info8); + info_ctr.info.info8 = &info8; + break; + case 9: + ZERO_STRUCT(info9); + info_ctr.info.info9 = &info9; + break; + } + + torture_comment(tctx, "Testing SetPrinter level %d, command %d\n", + info_ctr.level, r.in.command); + + torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter(p, tctx, &r), + "failed to call SetPrinter"); + + switch (r.in.command) { + case SPOOLSS_PRINTER_CONTROL_UNPAUSE: /* 0 */ + /* is ignored for all levels other then 0 */ + if (info_ctr.level > 0) { + /* ignored then */ + break; + } + case SPOOLSS_PRINTER_CONTROL_PAUSE: /* 1 */ + case SPOOLSS_PRINTER_CONTROL_RESUME: /* 2 */ + case SPOOLSS_PRINTER_CONTROL_PURGE: /* 3 */ + if (info_ctr.level > 0) { + /* is invalid for all levels other then 0 */ + torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PRINTER_COMMAND, + "unexpected error code returned"); + continue; + } else { + torture_assert_werr_ok(tctx, r.out.result, + "failed to call SetPrinter with non 0 command"); + continue; + } + break; + + case SPOOLSS_PRINTER_CONTROL_SET_STATUS: /* 4 */ + /* FIXME: gd needs further investigation */ + default: + torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PRINTER_COMMAND, + "unexpected error code returned"); + continue; + } + + switch (info_ctr.level) { + case 1: + torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, + "unexpected error code returned"); + break; + case 2: + torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_PRINTER_DRIVER, + "unexpected error code returned"); + break; + case 3: + case 4: + case 5: + case 7: + torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM, + "unexpected error code returned"); + break; + case 9: + torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, + "unexpected error code returned"); + break; + default: + torture_assert_werr_ok(tctx, r.out.result, + "failed to call SetPrinter"); + break; + } + } + + if (r.in.command < 5) { + r.in.command++; + goto again; + } + + return true; +} + +static void clear_info2(struct spoolss_SetPrinterInfoCtr *r) +{ + if ((r->level == 2) && (r->info.info2)) { + r->info.info2->secdesc = NULL; + r->info.info2->devmode = NULL; + } +} + +static bool test_PrinterInfo(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *handle) +{ + NTSTATUS status; + struct spoolss_SetPrinter s; + struct spoolss_GetPrinter q; + struct spoolss_GetPrinter q0; + struct spoolss_SetPrinterInfoCtr info_ctr; + union spoolss_PrinterInfo info; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + uint32_t needed; + bool ret = true; + int i; + + uint32_t status_list[] = { + /* these do not stick + PRINTER_STATUS_PAUSED, + PRINTER_STATUS_ERROR, + PRINTER_STATUS_PENDING_DELETION, */ + PRINTER_STATUS_PAPER_JAM, + PRINTER_STATUS_PAPER_OUT, + PRINTER_STATUS_MANUAL_FEED, + PRINTER_STATUS_PAPER_PROBLEM, + PRINTER_STATUS_OFFLINE, + PRINTER_STATUS_IO_ACTIVE, + PRINTER_STATUS_BUSY, + PRINTER_STATUS_PRINTING, + PRINTER_STATUS_OUTPUT_BIN_FULL, + PRINTER_STATUS_NOT_AVAILABLE, + PRINTER_STATUS_WAITING, + PRINTER_STATUS_PROCESSING, + PRINTER_STATUS_INITIALIZING, + PRINTER_STATUS_WARMING_UP, + PRINTER_STATUS_TONER_LOW, + PRINTER_STATUS_NO_TONER, + PRINTER_STATUS_PAGE_PUNT, + PRINTER_STATUS_USER_INTERVENTION, + PRINTER_STATUS_OUT_OF_MEMORY, + PRINTER_STATUS_DOOR_OPEN, + PRINTER_STATUS_SERVER_UNKNOWN, + PRINTER_STATUS_POWER_SAVE, + /* these do not stick + 0x02000000, + 0x04000000, + 0x08000000, + 0x10000000, + 0x20000000, + 0x40000000, + 0x80000000 */ + }; + uint32_t default_attribute = PRINTER_ATTRIBUTE_LOCAL; + uint32_t attribute_list[] = { + PRINTER_ATTRIBUTE_QUEUED, + /* fails with WERR_INVALID_DATATYPE: + PRINTER_ATTRIBUTE_DIRECT, */ + /* does not stick + PRINTER_ATTRIBUTE_DEFAULT, */ + PRINTER_ATTRIBUTE_SHARED, + /* does not stick + PRINTER_ATTRIBUTE_NETWORK, */ + PRINTER_ATTRIBUTE_HIDDEN, + PRINTER_ATTRIBUTE_LOCAL, + PRINTER_ATTRIBUTE_ENABLE_DEVQ, + PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS, + PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST, + PRINTER_ATTRIBUTE_WORK_OFFLINE, + /* does not stick + PRINTER_ATTRIBUTE_ENABLE_BIDI, */ + /* fails with WERR_INVALID_DATATYPE: + PRINTER_ATTRIBUTE_RAW_ONLY, */ + /* these do not stick + PRINTER_ATTRIBUTE_PUBLISHED, + PRINTER_ATTRIBUTE_FAX, + PRINTER_ATTRIBUTE_TS, + 0x00010000, + 0x00020000, + 0x00040000, + 0x00080000, + 0x00100000, + 0x00200000, + 0x00400000, + 0x00800000, + 0x01000000, + 0x02000000, + 0x04000000, + 0x08000000, + 0x10000000, + 0x20000000, + 0x40000000, + 0x80000000 */ + }; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + + s.in.handle = handle; + s.in.command = 0; + s.in.info_ctr = &info_ctr; + s.in.devmode_ctr = &devmode_ctr; + s.in.secdesc_ctr = &secdesc_ctr; + + q.in.handle = handle; + q.out.info = &info; + q0 = q; + +#define TESTGETCALL(call, r) \ + r.in.buffer = NULL; \ + r.in.offered = 0;\ + r.out.needed = &needed; \ + status = dcerpc_spoolss_ ##call(p, tctx, &r); \ + if (!NT_STATUS_IS_OK(status)) { \ + torture_comment(tctx, #call " level %u failed - %s (%s)\n", \ + r.in.level, nt_errstr(status), __location__); \ + ret = false; \ + break; \ + }\ + if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {\ + DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed); \ + data_blob_clear(&blob); \ + r.in.buffer = &blob; \ + r.in.offered = needed; \ + }\ + status = dcerpc_spoolss_ ##call(p, tctx, &r); \ + if (!NT_STATUS_IS_OK(status)) { \ + torture_comment(tctx, #call " level %u failed - %s (%s)\n", \ + r.in.level, nt_errstr(status), __location__); \ + ret = false; \ + break; \ + } \ + if (!W_ERROR_IS_OK(r.out.result)) { \ + torture_comment(tctx, #call " level %u failed - %s (%s)\n", \ + r.in.level, win_errstr(r.out.result), __location__); \ + ret = false; \ + break; \ + } + + +#define TESTSETCALL_EXP(call, r, err) \ + clear_info2(&info_ctr);\ + status = dcerpc_spoolss_ ##call(p, tctx, &r); \ + if (!NT_STATUS_IS_OK(status)) { \ + torture_comment(tctx, #call " level %u failed - %s (%s)\n", \ + r.in.info_ctr->level, nt_errstr(status), __location__); \ + ret = false; \ + break; \ + } \ + if (!W_ERROR_IS_OK(err)) { \ + if (!W_ERROR_EQUAL(err, r.out.result)) { \ + torture_comment(tctx, #call " level %u failed - %s, expected %s (%s)\n", \ + r.in.info_ctr->level, win_errstr(r.out.result), win_errstr(err), __location__); \ + ret = false; \ + } \ + break; \ + } \ + if (!W_ERROR_IS_OK(r.out.result)) { \ + torture_comment(tctx, #call " level %u failed - %s (%s)\n", \ + r.in.info_ctr->level, win_errstr(r.out.result), __location__); \ + ret = false; \ + break; \ + } + +#define TESTSETCALL(call, r) \ + TESTSETCALL_EXP(call, r, WERR_OK) + +#define STRING_EQUAL(s1, s2, field) \ + if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \ + torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \ + #field, s2, __location__); \ + ret = false; \ + break; \ + } + +#define MEM_EQUAL(s1, s2, length, field) \ + if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \ + torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \ + #field, (const char *)s2, __location__); \ + ret = false; \ + break; \ + } + +#define INT_EQUAL(i1, i2, field) \ + if (i1 != i2) { \ + torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \ + #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \ + ret = false; \ + break; \ + } + +#define TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, err) do { \ + torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \ + q.in.level = lvl1; \ + TESTGETCALL(GetPrinter, q) \ + info_ctr.level = lvl1; \ + info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \ + info_ctr.info.info ## lvl1->field1 = value;\ + TESTSETCALL_EXP(SetPrinter, s, err) \ + info_ctr.info.info ## lvl1->field1 = ""; \ + TESTGETCALL(GetPrinter, q) \ + info_ctr.info.info ## lvl1->field1 = value; \ + STRING_EQUAL(info_ctr.info.info ## lvl1->field1, value, field1); \ + q.in.level = lvl2; \ + TESTGETCALL(GetPrinter, q) \ + info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)&q.out.info->info ## lvl2; \ + STRING_EQUAL(info_ctr.info.info ## lvl2->field2, value, field2); \ + } while (0) + +#define TEST_PRINTERINFO_STRING(lvl1, field1, lvl2, field2, value) do { \ + TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, WERR_OK); \ + } while (0); + +#define TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value) do { \ + torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \ + q.in.level = lvl1; \ + TESTGETCALL(GetPrinter, q) \ + info_ctr.level = lvl1; \ + info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \ + info_ctr.info.info ## lvl1->field1 = value; \ + TESTSETCALL(SetPrinter, s) \ + info_ctr.info.info ## lvl1->field1 = 0; \ + TESTGETCALL(GetPrinter, q) \ + info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \ + INT_EQUAL(info_ctr.info.info ## lvl1->field1, exp_value, field1); \ + q.in.level = lvl2; \ + TESTGETCALL(GetPrinter, q) \ + info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)&q.out.info->info ## lvl2; \ + INT_EQUAL(info_ctr.info.info ## lvl2->field2, exp_value, field1); \ + } while (0) + +#define TEST_PRINTERINFO_INT(lvl1, field1, lvl2, field2, value) do { \ + TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value); \ + } while (0) + + q0.in.level = 0; + do { TESTGETCALL(GetPrinter, q0) } while (0); + + TEST_PRINTERINFO_STRING(2, comment, 1, comment, "xx2-1 comment"); + TEST_PRINTERINFO_STRING(2, comment, 2, comment, "xx2-2 comment"); + + /* level 0 printername does not stick */ +/* TEST_PRINTERINFO_STRING(2, printername, 0, printername, "xx2-0 printer"); */ + TEST_PRINTERINFO_STRING(2, printername, 1, name, "xx2-1 printer"); + TEST_PRINTERINFO_STRING(2, printername, 2, printername, "xx2-2 printer"); + TEST_PRINTERINFO_STRING(2, printername, 4, printername, "xx2-4 printer"); + TEST_PRINTERINFO_STRING(2, printername, 5, printername, "xx2-5 printer"); +/* TEST_PRINTERINFO_STRING(4, printername, 0, printername, "xx4-0 printer"); */ + TEST_PRINTERINFO_STRING(4, printername, 1, name, "xx4-1 printer"); + TEST_PRINTERINFO_STRING(4, printername, 2, printername, "xx4-2 printer"); + TEST_PRINTERINFO_STRING(4, printername, 4, printername, "xx4-4 printer"); + TEST_PRINTERINFO_STRING(4, printername, 5, printername, "xx4-5 printer"); +/* TEST_PRINTERINFO_STRING(5, printername, 0, printername, "xx5-0 printer"); */ + TEST_PRINTERINFO_STRING(5, printername, 1, name, "xx5-1 printer"); + TEST_PRINTERINFO_STRING(5, printername, 2, printername, "xx5-2 printer"); + TEST_PRINTERINFO_STRING(5, printername, 4, printername, "xx5-4 printer"); + TEST_PRINTERINFO_STRING(5, printername, 5, printername, "xx5-5 printer"); + + /* servername can be set but does not stick + TEST_PRINTERINFO_STRING(2, servername, 0, servername, "xx2-0 servername"); + TEST_PRINTERINFO_STRING(2, servername, 2, servername, "xx2-2 servername"); + TEST_PRINTERINFO_STRING(2, servername, 4, servername, "xx2-4 servername"); + */ + + /* passing an invalid port will result in WERR_UNKNOWN_PORT */ + TEST_PRINTERINFO_STRING_EXP_ERR(2, portname, 2, portname, "xx2-2 portname", WERR_UNKNOWN_PORT); + TEST_PRINTERINFO_STRING_EXP_ERR(2, portname, 5, portname, "xx2-5 portname", WERR_UNKNOWN_PORT); + TEST_PRINTERINFO_STRING_EXP_ERR(5, portname, 2, portname, "xx5-2 portname", WERR_UNKNOWN_PORT); + TEST_PRINTERINFO_STRING_EXP_ERR(5, portname, 5, portname, "xx5-5 portname", WERR_UNKNOWN_PORT); + + TEST_PRINTERINFO_STRING(2, sharename, 2, sharename, "xx2-2 sharename"); + /* passing an invalid driver will result in WERR_UNKNOWN_PRINTER_DRIVER */ + TEST_PRINTERINFO_STRING_EXP_ERR(2, drivername, 2, drivername, "xx2-2 drivername", WERR_UNKNOWN_PRINTER_DRIVER); + TEST_PRINTERINFO_STRING(2, location, 2, location, "xx2-2 location"); + /* passing an invalid sepfile will result in WERR_INVALID_SEPARATOR_FILE */ + TEST_PRINTERINFO_STRING_EXP_ERR(2, sepfile, 2, sepfile, "xx2-2 sepfile", WERR_INVALID_SEPARATOR_FILE); + /* passing an invalid printprocessor will result in WERR_UNKNOWN_PRINTPROCESSOR */ + TEST_PRINTERINFO_STRING_EXP_ERR(2, printprocessor, 2, printprocessor, "xx2-2 printprocessor", WERR_UNKNOWN_PRINTPROCESSOR); + TEST_PRINTERINFO_STRING(2, datatype, 2, datatype, "xx2-2 datatype"); + TEST_PRINTERINFO_STRING(2, parameters, 2, parameters, "xx2-2 parameters"); + + for (i=0; i < ARRAY_SIZE(attribute_list); i++) { +/* TEST_PRINTERINFO_INT_EXP(2, attributes, 1, flags, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); */ + TEST_PRINTERINFO_INT_EXP(2, attributes, 2, attributes, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); + TEST_PRINTERINFO_INT_EXP(2, attributes, 4, attributes, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); + TEST_PRINTERINFO_INT_EXP(2, attributes, 5, attributes, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); +/* TEST_PRINTERINFO_INT_EXP(4, attributes, 1, flags, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); */ + TEST_PRINTERINFO_INT_EXP(4, attributes, 2, attributes, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); + TEST_PRINTERINFO_INT_EXP(4, attributes, 4, attributes, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); + TEST_PRINTERINFO_INT_EXP(4, attributes, 5, attributes, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); +/* TEST_PRINTERINFO_INT_EXP(5, attributes, 1, flags, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); */ + TEST_PRINTERINFO_INT_EXP(5, attributes, 2, attributes, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); + TEST_PRINTERINFO_INT_EXP(5, attributes, 4, attributes, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); + TEST_PRINTERINFO_INT_EXP(5, attributes, 5, attributes, + attribute_list[i], + (attribute_list[i] | default_attribute) + ); + } + + for (i=0; i < ARRAY_SIZE(status_list); i++) { + /* level 2 sets do not stick + TEST_PRINTERINFO_INT(2, status, 0, status, status_list[i]); + TEST_PRINTERINFO_INT(2, status, 2, status, status_list[i]); + TEST_PRINTERINFO_INT(2, status, 6, status, status_list[i]); */ + TEST_PRINTERINFO_INT(6, status, 0, status, status_list[i]); + TEST_PRINTERINFO_INT(6, status, 2, status, status_list[i]); + TEST_PRINTERINFO_INT(6, status, 6, status, status_list[i]); + } + + /* priorities need to be between 0 and 99 + passing an invalid priority will result in WERR_INVALID_PRIORITY */ + TEST_PRINTERINFO_INT(2, priority, 2, priority, 0); + TEST_PRINTERINFO_INT(2, priority, 2, priority, 1); + TEST_PRINTERINFO_INT(2, priority, 2, priority, 99); + /* TEST_PRINTERINFO_INT(2, priority, 2, priority, 100); */ + TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 0); + TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 1); + TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 99); + /* TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 100); */ + + TEST_PRINTERINFO_INT(2, starttime, 2, starttime, __LINE__); + TEST_PRINTERINFO_INT(2, untiltime, 2, untiltime, __LINE__); + + /* does not stick + TEST_PRINTERINFO_INT(2, cjobs, 2, cjobs, __LINE__); + TEST_PRINTERINFO_INT(2, averageppm, 2, averageppm, __LINE__); */ + + /* does not stick + TEST_PRINTERINFO_INT(5, device_not_selected_timeout, 5, device_not_selected_timeout, __LINE__); + TEST_PRINTERINFO_INT(5, transmission_retry_timeout, 5, transmission_retry_timeout, __LINE__); */ + + /* FIXME: gd also test devmode and secdesc behavior */ + + { + /* verify composition of level 1 description field */ + const char *description; + const char *tmp; + + q0.in.level = 1; + do { TESTGETCALL(GetPrinter, q0) } while (0); + + description = talloc_strdup(tctx, q0.out.info->info1.description); + + q0.in.level = 2; + do { TESTGETCALL(GetPrinter, q0) } while (0); + + tmp = talloc_asprintf(tctx, "%s,%s,%s", + q0.out.info->info2.printername, + q0.out.info->info2.drivername, + q0.out.info->info2.location); + + do { STRING_EQUAL(description, tmp, "description")} while (0); + } + + return ret; +} + static bool test_ClosePrinter(struct torture_context *tctx, struct dcerpc_pipe *p, -- cgit From b6fb8cf5f38fc434103936b41a5793f5943c129a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 3 Jul 2009 09:56:28 +0200 Subject: s4-smbtorture: add RPC-SPOOLSS-PRINTER test. Guenther --- source4/torture/rpc/rpc.c | 1 + source4/torture/rpc/spoolss.c | 443 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 444 insertions(+) diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c index 4043562ab5..6eeba7f66c 100644 --- a/source4/torture/rpc/rpc.c +++ b/source4/torture/rpc/rpc.c @@ -444,6 +444,7 @@ NTSTATUS torture_rpc_init(void) torture_suite_add_simple_test(suite, "SPOOLSS", torture_rpc_spoolss); torture_suite_add_suite(suite, torture_rpc_spoolss_notify(suite)); torture_suite_add_suite(suite, torture_rpc_spoolss_win(suite)); + torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite)); torture_suite_add_simple_test(suite, "SAMR", torture_rpc_samr); torture_suite_add_simple_test(suite, "SAMR-USERS", torture_rpc_samr_users); torture_suite_add_simple_test(suite, "SAMR-PASSWORDS", torture_rpc_samr_passwords); diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index b6ad1a77c2..a515ef6baa 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -26,6 +26,11 @@ #include "torture/rpc/rpc.h" #include "librpc/gen_ndr/ndr_spoolss_c.h" +#define TORTURE_WELLKNOWN_PRINTER "torture_wkn_printer" +#define TORTURE_PRINTER "torture_printer" +#define TORTURE_WELLKNOWN_PRINTER_EX "torture_wkn_printer_ex" +#define TORTURE_PRINTER_EX "torture_printer_ex" + struct test_spoolss_context { /* print server handle */ struct policy_handle server_handle; @@ -2633,6 +2638,432 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx, return true; } +static bool test_DeletePrinter(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *handle) +{ + struct spoolss_DeletePrinter r; + + torture_comment(tctx, "Testing DeletePrinter\n"); + + r.in.handle = handle; + + torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_DeletePrinter(p, tctx, &r), + "failed to delete printer"); + torture_assert_werr_ok(tctx, r.out.result, + "failed to delete printer"); + + return true; +} + +static bool test_EnumPrinters_findname(struct torture_context *tctx, + struct dcerpc_pipe *p, + uint32_t flags, + uint32_t level, + const char *name, + bool *found) +{ + struct spoolss_EnumPrinters e; + uint32_t count; + union spoolss_PrinterInfo *info; + uint32_t needed; + int i; + + *found = false; + + e.in.flags = flags; + e.in.server = NULL; + e.in.level = level; + e.in.buffer = NULL; + e.in.offered = 0; + e.out.count = &count; + e.out.info = &info; + e.out.needed = &needed; + + torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters(p, tctx, &e), + "failed to enum printers"); + + if (W_ERROR_EQUAL(e.out.result, WERR_INSUFFICIENT_BUFFER)) { + DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed); + data_blob_clear(&blob); + e.in.buffer = &blob; + e.in.offered = needed; + + torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters(p, tctx, &e), + "failed to enum printers"); + } + + torture_assert_werr_ok(tctx, e.out.result, + "failed to enum printers"); + + for (i=0; i < count; i++) { + + const char *current = NULL; + + switch (level) { + case 1: + current = info[i].info1.name; + break; + } + + if (strequal(current, name)) { + *found = true; + break; + } + } + + return true; +} + +static bool test_AddPrinter_wellknown(struct torture_context *tctx, + struct dcerpc_pipe *p, + const char *printername, + bool ex) +{ + WERROR result; + struct spoolss_AddPrinter r; + struct spoolss_AddPrinterEx rex; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_SetPrinterInfo1 info1; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + struct spoolss_UserLevelCtr userlevel_ctr; + struct policy_handle handle; + bool found = false; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + ZERO_STRUCT(userlevel_ctr); + ZERO_STRUCT(info1); + + torture_comment(tctx, "Testing AddPrinter%s level 1\n", ex ? "Ex":""); + + /* try to add printer to wellknown printer list (level 1) */ + + userlevel_ctr.level = 1; + + info_ctr.info.info1 = &info1; + info_ctr.level = 1; + + rex.in.server = NULL; + rex.in.info_ctr = &info_ctr; + rex.in.devmode_ctr = &devmode_ctr; + rex.in.secdesc_ctr = &secdesc_ctr; + rex.in.userlevel_ctr = &userlevel_ctr; + rex.out.handle = &handle; + + r.in.server = NULL; + r.in.info_ctr = &info_ctr; + r.in.devmode_ctr = &devmode_ctr; + r.in.secdesc_ctr = &secdesc_ctr; + r.out.handle = &handle; + + torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) : + dcerpc_spoolss_AddPrinter(p, tctx, &r), + "failed to add printer"); + result = ex ? rex.out.result : r.out.result; + torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME, + "unexpected result code"); + + info1.name = printername; + info1.flags = PRINTER_ATTRIBUTE_SHARED; + + torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) : + dcerpc_spoolss_AddPrinter(p, tctx, &r), + "failed to add printer"); + result = ex ? rex.out.result : r.out.result; + torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS, + "unexpected result code"); + + /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here, + better do a real check to see the printer is really there */ + + torture_assert(tctx, test_EnumPrinters_findname(tctx, p, + PRINTER_ENUM_NETWORK, 1, + printername, + &found), + "failed to enum printers"); + + torture_assert(tctx, found, "failed to find newly added printer"); + + info1.flags = 0; + + torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) : + dcerpc_spoolss_AddPrinter(p, tctx, &r), + "failed to add printer"); + result = ex ? rex.out.result : r.out.result; + torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS, + "unexpected result code"); + + /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here, + better do a real check to see the printer has really been removed + from the well known printer list */ + + found = false; + + torture_assert(tctx, test_EnumPrinters_findname(tctx, p, + PRINTER_ENUM_NETWORK, 1, + printername, + &found), + "failed to enum printers"); +#if 0 + torture_assert(tctx, !found, "printer still in well known printer list"); +#endif + return true; +} + +static bool test_AddPrinter_normal(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *handle_p, + const char *printername, + const char *drivername, + const char *portname, + bool ex) +{ + WERROR result; + struct spoolss_AddPrinter r; + struct spoolss_AddPrinterEx rex; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_SetPrinterInfo2 info2; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + struct spoolss_UserLevelCtr userlevel_ctr; + struct policy_handle handle; + bool found = false; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + ZERO_STRUCT(userlevel_ctr); + + torture_comment(tctx, "Testing AddPrinter%s level 2\n", ex ? "Ex":""); + + userlevel_ctr.level = 1; + + rex.in.server = NULL; + rex.in.info_ctr = &info_ctr; + rex.in.devmode_ctr = &devmode_ctr; + rex.in.secdesc_ctr = &secdesc_ctr; + rex.in.userlevel_ctr = &userlevel_ctr; + rex.out.handle = &handle; + + r.in.server = NULL; + r.in.info_ctr = &info_ctr; + r.in.devmode_ctr = &devmode_ctr; + r.in.secdesc_ctr = &secdesc_ctr; + r.out.handle = &handle; + + again: + + /* try to add printer to printer list (level 2) */ + + ZERO_STRUCT(info2); + + info_ctr.info.info2 = &info2; + info_ctr.level = 2; + + torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) : + dcerpc_spoolss_AddPrinter(p, tctx, &r), + "failed to add printer"); + result = ex ? rex.out.result : r.out.result; + torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME, + "unexpected result code"); + + info2.printername = printername; + + torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) : + dcerpc_spoolss_AddPrinter(p, tctx, &r), + "failed to add printer"); + result = ex ? rex.out.result : r.out.result; + + if (W_ERROR_EQUAL(result, WERR_PRINTER_ALREADY_EXISTS)) { + struct policy_handle printer_handle; + + torture_assert(tctx, call_OpenPrinterEx(tctx, p, printername, &printer_handle), + "failed to open printer handle"); + + torture_assert(tctx, test_DeletePrinter(tctx, p, &printer_handle), + "failed to delete printer"); + + torture_assert(tctx, test_ClosePrinter(tctx, p, &printer_handle), + "failed to close server handle"); + + goto again; + } + + torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PORT, + "unexpected result code"); + + info2.portname = portname; + + torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) : + dcerpc_spoolss_AddPrinter(p, tctx, &r), + "failed to add printer"); + result = ex ? rex.out.result : r.out.result; + torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTER_DRIVER, + "unexpected result code"); + + info2.drivername = drivername; + + torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) : + dcerpc_spoolss_AddPrinter(p, tctx, &r), + "failed to add printer"); + result = ex ? rex.out.result : r.out.result; + torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTPROCESSOR, + "unexpected result code"); + + info2.printprocessor = "winprint"; + + torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) : + dcerpc_spoolss_AddPrinter(p, tctx, &r), + "failed to add printer"); + result = ex ? rex.out.result : r.out.result; + torture_assert_werr_ok(tctx, result, + "failed to add printer"); + + *handle_p = handle; + + /* we are paranoid, really check if the printer is there now */ + + torture_assert(tctx, test_EnumPrinters_findname(tctx, p, + PRINTER_ENUM_LOCAL, 1, + printername, + &found), + "failed to enum printers"); + torture_assert(tctx, found, "failed to find newly added printer"); + + torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) : + dcerpc_spoolss_AddPrinter(p, tctx, &r), + "failed to add printer"); + result = ex ? rex.out.result : r.out.result; + torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS, + "unexpected result code"); + + return true; +} + +static bool test_AddPrinterEx(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *handle_p, + const char *printername, + const char *drivername, + const char *portname) +{ + bool ret = true; + + if (!torture_setting_bool(tctx, "samba3", false)) { + if (!test_AddPrinter_wellknown(tctx, p, TORTURE_WELLKNOWN_PRINTER_EX, true)) { + torture_comment(tctx, "failed to add printer to well known list\n"); + ret = false; + } + } + + if (!test_AddPrinter_normal(tctx, p, handle_p, + printername, drivername, portname, + true)) { + torture_comment(tctx, "failed to add printer to printer list\n"); + ret = false; + } + + return ret; +} + +static bool test_AddPrinter(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *handle_p, + const char *printername, + const char *drivername, + const char *portname) +{ + bool ret = true; + + if (!torture_setting_bool(tctx, "samba3", false)) { + if (!test_AddPrinter_wellknown(tctx, p, TORTURE_WELLKNOWN_PRINTER, false)) { + torture_comment(tctx, "failed to add printer to well known list\n"); + ret = false; + } + } + + if (!test_AddPrinter_normal(tctx, p, handle_p, + printername, drivername, portname, + false)) { + torture_comment(tctx, "failed to add printer to printer list\n"); + ret = false; + } + + return ret; +} + +static bool test_printer_info(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *handle) +{ + bool ret = true; + + if (!test_PrinterInfo(tctx, p, handle)) { + ret = false; + } + + if (!test_SetPrinter_errors(tctx, p, handle)) { + ret = false; + } + + return ret; +} + +static bool test_printer(struct torture_context *tctx, + struct dcerpc_pipe *p) +{ + bool ret = true; + struct policy_handle handle[2]; + bool found = false; + const char *drivername = "Microsoft XPS Document Writer"; + const char *portname = "LPT1:"; + + /* test printer created via AddPrinter */ + + if (!test_AddPrinter(tctx, p, &handle[0], TORTURE_PRINTER, drivername, portname)) { + return false; + } + + if (!test_printer_info(tctx, p, &handle[0])) { + ret = false; + } + + if (!test_DeletePrinter(tctx, p, &handle[0])) { + ret = false; + } + + if (!test_EnumPrinters_findname(tctx, p, PRINTER_ENUM_LOCAL, 1, + TORTURE_PRINTER, &found)) { + ret = false; + } + + torture_assert(tctx, !found, "deleted printer still there"); + + /* test printer created via AddPrinterEx */ + + if (!test_AddPrinterEx(tctx, p, &handle[1], TORTURE_PRINTER_EX, drivername, portname)) { + return false; + } + + if (!test_printer_info(tctx, p, &handle[1])) { + ret = false; + } + + if (!test_DeletePrinter(tctx, p, &handle[1])) { + ret = false; + } + + if (!test_EnumPrinters_findname(tctx, p, PRINTER_ENUM_LOCAL, 1, + TORTURE_PRINTER_EX, &found)) { + ret = false; + } + + torture_assert(tctx, !found, "deleted printer still there"); + + return ret; +} + bool torture_rpc_spoolss(struct torture_context *torture) { NTSTATUS status; @@ -2689,3 +3120,15 @@ bool torture_rpc_spoolss(struct torture_context *torture) return ret; } + +struct torture_suite *torture_rpc_spoolss_printer(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, "SPOOLSS-PRINTER"); + + struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite, + "printer", &ndr_table_spoolss); + + torture_rpc_tcase_add_test(tcase, "printer", test_printer); + + return suite; +} -- cgit From d05054133009526bd9dd08a226747e5cfeef8fc7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 23:12:59 +0200 Subject: Fix bug 5886 Ok, that's a very long-standing one. I finally got around to install a recent OpenLDAP and test the different variants of setting a NULL password etc. Thanks all for your patience! Volker --- source3/passdb/pdb_ldap.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 11554a76ac..1b1e22f2c8 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1701,6 +1701,7 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, char *utf8_password; char *utf8_dn; size_t converted_size; + int ret; if (!ldap_state->is_nds_ldap) { @@ -1732,14 +1733,31 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, } if ((ber_printf (ber, "{") < 0) || - (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn) < 0) || - (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password) < 0) || - (ber_printf (ber, "n}") < 0)) { - DEBUG(0,("ldapsam_modify_entry: ber_printf returns a value <0\n")); - ber_free(ber,1); - TALLOC_FREE(utf8_dn); - TALLOC_FREE(utf8_password); - return NT_STATUS_UNSUCCESSFUL; + (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, + utf8_dn) < 0)) { + DEBUG(0,("ldapsam_modify_entry: ber_printf returns a " + "value <0\n")); + ber_free(ber,1); + TALLOC_FREE(utf8_dn); + TALLOC_FREE(utf8_password); + return NT_STATUS_UNSUCCESSFUL; + } + + if ((utf8_password != NULL) && (*utf8_password != '\0')) { + ret = ber_printf(ber, "ts}", + LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, + utf8_password); + } else { + ret = ber_printf(ber, "}"); + } + + if (ret < 0) { + DEBUG(0,("ldapsam_modify_entry: ber_printf returns a " + "value <0\n")); + ber_free(ber,1); + TALLOC_FREE(utf8_dn); + TALLOC_FREE(utf8_password); + return NT_STATUS_UNSUCCESSFUL; } if ((rc = ber_flatten (ber, &bv))<0) { -- cgit From 4b6401ab2cce8319abe0f8176bb460d51bd4a390 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 14 Jul 2009 23:36:41 +0200 Subject: s3-passdb: fix wbc build warning. Guenther --- source3/passdb/pdb_wbc_sam.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c index ec54d553d1..2161d2ff5c 100644 --- a/source3/passdb/pdb_wbc_sam.c +++ b/source3/passdb/pdb_wbc_sam.c @@ -167,12 +167,12 @@ done: return result; } -static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value) +static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value) { return NT_STATUS_UNSUCCESSFUL; } -static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value) +static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value) { return NT_STATUS_UNSUCCESSFUL; } -- cgit From 5334b79142e32c39c56cea2e9c0d5b08e2f217ca Mon Sep 17 00:00:00 2001 From: Aravind Date: Tue, 7 Jul 2009 07:11:56 -0700 Subject: torture/smb2: Adding SMB2 Directory enumeration torture tests. * Most of the tests were ported from SMB torture tests. * Added one new tests which checks the behavior of the file_index field present in SMB2_FIND struct. * Added one new test to check the enumeration of directories containing lots of files (~2000 files) with name lengths varying from 1 to 200 char. --- source4/torture/smb2/config.mk | 1 + source4/torture/smb2/dir.c | 1289 +++++++++++++++++++++++++++++++++++++++- source4/torture/smb2/smb2.c | 1 + 3 files changed, 1265 insertions(+), 26 deletions(-) diff --git a/source4/torture/smb2/config.mk b/source4/torture/smb2/config.mk index bc4fc15e07..b321b41bdd 100644 --- a/source4/torture/smb2/config.mk +++ b/source4/torture/smb2/config.mk @@ -22,6 +22,7 @@ TORTURE_SMB2_OBJ_FILES = $(addprefix $(torturesrcdir)/smb2/, \ smb2.o \ durable_open.o \ oplocks.o \ + dir.o \ lease.o \ create.o \ read.o \ diff --git a/source4/torture/smb2/dir.c b/source4/torture/smb2/dir.c index 58cf2229bc..79672ef03a 100644 --- a/source4/torture/smb2/dir.c +++ b/source4/torture/smb2/dir.c @@ -1,20 +1,22 @@ -/* +/* Unix SMB/CIFS implementation. SMB2 dir list test suite Copyright (C) Andrew Tridgell 2005 - + Copyright (C) Zachary Loafman 2009 + Copyright (C) Aravind Srinivasan 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 . */ @@ -22,72 +24,1307 @@ #include "includes.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#include "libcli/smb_composite/smb_composite.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" +#include "libcli/libcli.h" #include "torture/torture.h" #include "torture/smb2/proto.h" +#include "torture/util.h" + +#include "system/filesys.h" + +#define CHECK_STATUS(status, correct) do { \ + if (!NT_STATUS_EQUAL(status, correct)) { \ + torture_result(tctx, TORTURE_FAIL, __location__": \ + Incorrect status %s - should be %s", \ + nt_errstr(status), nt_errstr(correct)); \ + ret = false; \ + goto done; \ + }} while (0) + +#define CHECK_VALUE(v, correct) torture_assert_int_equal(tctx, (v), \ + (correct), "incorrect value"); + +#define DNAME "smb2_dir" +#define NFILES 100 + +struct file_elem { + char *name; + bool found; +}; + +static NTSTATUS populate_tree(struct torture_context *tctx, + TALLOC_CTX *mem_ctx, + struct smb2_tree *tree, + struct file_elem *files, + int nfiles, + struct smb2_handle *h_out) +{ + struct smb2_create create; + NTSTATUS status; + bool ret; + int i; + + smb2_deltree(tree, DNAME); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_DIR_ALL; + create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; + create.in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE; + create.in.create_disposition = NTCREATEX_DISP_CREATE; + create.in.fname = DNAME; + + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + *h_out = create.out.file.handle; + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.create_disposition = NTCREATEX_DISP_CREATE; + + for (i = 0; i < nfiles; i++) { + files[i].name = generate_random_str(tctx, 8); + create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", + DNAME, files[i].name); + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + smb2_util_close(tree, create.out.file.handle); + } + done: + return status; +} /* test find continue */ -static bool torture_smb2_find_dir(struct smb2_tree *tree) + +static bool test_find(struct torture_context *tctx, + struct smb2_tree *tree) { - struct smb2_handle handle; - NTSTATUS status; - int i; + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_handle h; struct smb2_find f; - bool ret = true; union smb_search_data *d; + struct file_elem files[NFILES] = {}; + NTSTATUS status; + bool ret = true; uint_t count; + int i, j, file_count = 0; - status = smb2_util_roothandle(tree, &handle); - if (!NT_STATUS_IS_OK(status)) { - return false; + status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h); + + ZERO_STRUCT(f); + f.in.file.handle = h; + f.in.pattern = "*"; + f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE; + f.in.max_response_size = 0x100; + f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO; + + do { + status = smb2_find_level(tree, tree, &f, &count, &d); + if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) + break; + CHECK_STATUS(status, NT_STATUS_OK); + + for (i = 0; i < count; i++) { + bool expected; + const char *found = d[i].both_directory_info.name.s; + + if (!strcmp(found, ".") || !strcmp(found, "..")) + continue; + + expected = false; + for (j = 0; j < NFILES; j++) { + if (!strcmp(files[j].name, found)) { + files[j].found = true; + expected = true; + break; + } + } + + if (expected) + continue; + + torture_result(tctx, TORTURE_FAIL, + "(%s): didn't expect %s\n", + __location__, found); + ret = false; + goto done; + } + + file_count = file_count + i; + f.in.continue_flags = 0; + f.in.max_response_size = 4096; + } while (count != 0); + + CHECK_VALUE(file_count, NFILES + 2); + + for (i = 0; i < NFILES; i++) { + if (files[j].found) + continue; + + torture_result(tctx, TORTURE_FAIL, + "(%s): expected to find %s, but didn't\n", + __location__, files[j].name); + ret = false; + goto done; } + done: + smb2_deltree(tree, DNAME); + talloc_free(mem_ctx); + + return ret; +} + +/* + test fixed enumeration +*/ + +static bool test_fixed(struct torture_context *tctx, + struct smb2_tree *tree) +{ + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_create create; + struct smb2_handle h, h2; + struct smb2_find f; + union smb_search_data *d; + struct file_elem files[NFILES] = {}; + NTSTATUS status; + bool ret = true; + uint_t count; + int i; + + status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_DIR_ALL; + create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; + create.in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE; + create.in.create_disposition = NTCREATEX_DISP_OPEN; + create.in.fname = DNAME; + + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + h2 = create.out.file.handle; + ZERO_STRUCT(f); - f.in.file.handle = handle; + f.in.file.handle = h; f.in.pattern = "*"; f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE; f.in.max_response_size = 0x100; f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO; + /* Start enumeration on h, then delete all from h2 */ + status = smb2_find_level(tree, tree, &f, &count, &d); + CHECK_STATUS(status, NT_STATUS_OK); + + f.in.file.handle = h2; + do { status = smb2_find_level(tree, tree, &f, &count, &d); - if (!NT_STATUS_IS_OK(status)) { - printf("SMB2_FIND_ID_BOTH_DIRECTORY_INFO failed - %s\n", nt_errstr(status)); + if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) break; + CHECK_STATUS(status, NT_STATUS_OK); + + for (i = 0; i < count; i++) { + const char *found = d[i].both_directory_info.name.s; + char *path = talloc_asprintf(mem_ctx, "%s\\%s", + DNAME, found); + + if (!strcmp(found, ".") || !strcmp(found, "..")) + continue; + + status = smb2_util_unlink(tree, path); + CHECK_STATUS(status, NT_STATUS_OK); + + talloc_free(path); } - printf("Got %d files\n", count); - for (i=0;isname1.field1) != (v.sname2.out.field2)) { \ + printf("(%s) %s/%s [0x%x] != %s/%s [0x%x]\n", \ + __location__, \ + #sname1, #field1, (int)s->sname1.field1, \ + #sname2, #field2, (int)v.sname2.out.field2); \ + ret = false; \ + } \ + }} while (0) + +#define CHECK_TIME(name, sname1, field1, v, sname2, field2) do { \ + s = find(name); \ + if (s) { \ + if (s->sname1.field1 != \ + (~1 & nt_time_to_unix(v.sname2.out.field2))) { \ + printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ + __location__, \ + #sname1, #field1, \ + timestring(tctx, s->sname1.field1), \ + #sname2, #field2, \ + nt_time_string(tctx, v.sname2.out.field2)); \ + ret = false; \ + } \ + }} while (0) + +#define CHECK_NTTIME(name, sname1, field1, v, sname2, field2) do { \ + s = find(name); \ + if (s) { \ + if (s->sname1.field1 != v.sname2.out.field2) { \ + printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ + __location__, \ + #sname1, #field1, \ + nt_time_string(tctx, s->sname1.field1), \ + #sname2, #field2, \ + nt_time_string(tctx, v.sname2.out.field2)); \ + ret = false; \ + } \ + }} while (0) + +#define CHECK_STR(name, sname1, field1, v, sname2, field2) do { \ + s = find(name); \ + if (s) { \ + if (!s->sname1.field1 || \ + strcmp(s->sname1.field1, v.sname2.out.field2.s)) { \ + printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ + __location__, \ + #sname1, #field1, s->sname1.field1, \ + #sname2, #field2, v.sname2.out.field2.s); \ + ret = false; \ + } \ + }} while (0) + +#define CHECK_WSTR(name, sname1, field1, v, sname2, field2, flags) do { \ + s = find(name); \ + if (s) { \ + if (!s->sname1.field1.s || \ + strcmp(s->sname1.field1.s, v.sname2.out.field2.s)) { \ + printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ + __location__, \ + #sname1, #field1, s->sname1.field1.s, \ + #sname2, #field2, v.sname2.out.field2.s); \ + ret = false; \ + } \ + }} while (0) + +#define CHECK_NAME(name, sname1, field1, fname, flags) do { \ + s = find(name); \ + if (s) { \ + if (!s->sname1.field1.s || \ + strcmp(s->sname1.field1.s, fname)) { \ + printf("(%s) %s/%s [%s] != %s\n", \ + __location__, \ + #sname1, #field1, s->sname1.field1.s, \ + fname); \ + ret = false; \ + } \ + }} while (0) + +#define CHECK_UNIX_NAME(name, sname1, field1, fname, flags) do { \ + s = find(name); \ + if (s) { \ + if (!s->sname1.field1 || \ + strcmp(s->sname1.field1, fname)) { \ + printf("(%s) %s/%s [%s] != %s\n", \ + __location__, \ + #sname1, #field1, s->sname1.field1, \ + fname); \ + ret = false; \ + } \ + }} while (0) + + /* check that all the results are as expected */ + CHECK_VAL("SMB2_FIND_DIRECTORY_INFO", directory_info, attrib, all_info2, all_info2, attrib); + CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, attrib, all_info2, all_info2, attrib); + CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, attrib, all_info2, all_info2, attrib); + CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, attrib, all_info2, all_info2, attrib); + CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, attrib, all_info2, all_info2, attrib); + + CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, write_time, all_info2, all_info2, write_time); + CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, write_time, all_info2, all_info2, write_time); + CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, write_time, all_info2, all_info2, write_time); + CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, write_time, all_info2, all_info2, write_time); + CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, write_time, all_info2, all_info2, write_time); + + CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, create_time, all_info2, all_info2, create_time); + CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, create_time, all_info2, all_info2, create_time); + CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, create_time, all_info2, all_info2, create_time); + CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, create_time, all_info2, all_info2, create_time); + CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, create_time, all_info2, all_info2, create_time); + CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, access_time, all_info2, all_info2, access_time); + CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, access_time, all_info2, all_info2, access_time); + CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, access_time, all_info2, all_info2, access_time); + CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, access_time, all_info2, all_info2, access_time); + CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, access_time, all_info2, all_info2, access_time); + + CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, change_time, all_info2, all_info2, change_time); + CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, change_time, all_info2, all_info2, change_time); + CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, change_time, all_info2, all_info2, change_time); + CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, change_time, all_info2, all_info2, change_time); + CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, change_time, all_info2, all_info2, change_time); + + CHECK_VAL("SMB2_FIND_DIRECTORY_INFO", directory_info, size, all_info2, all_info2, size); + CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, size, all_info2, all_info2, size); + CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, size, all_info2, all_info2, size); + CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, size, all_info2, all_info2, size); + CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, size, all_info2, all_info2, size); + + CHECK_VAL("SMB2_FIND_DIRECTORY_INFO", directory_info, alloc_size, all_info2, all_info2, alloc_size); + CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, alloc_size, all_info2, all_info2, alloc_size); + CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, alloc_size, all_info2, all_info2, alloc_size); + CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, alloc_size, all_info2, all_info2, alloc_size); + CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, alloc_size, all_info2, all_info2, alloc_size); + + CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, ea_size, all_info2, all_info2, ea_size); + CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, ea_size, all_info2, all_info2, ea_size); + CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, ea_size, all_info2, all_info2, ea_size); + CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, ea_size, all_info2, all_info2, ea_size); + + CHECK_WSTR("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, short_name, alt_info, alt_name_info, fname, STR_UNICODE); + + CHECK_NAME("SMB2_FIND_DIRECTORY_INFO", directory_info, name, fname, STR_TERMINATE_ASCII); + CHECK_NAME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, name, fname, STR_TERMINATE_ASCII); + CHECK_NAME("SMB2_FIND_NAME_INFO", name_info, name, fname, STR_TERMINATE_ASCII); + CHECK_NAME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, name, fname, STR_TERMINATE_ASCII); + CHECK_NAME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, name, fname, STR_TERMINATE_ASCII); + CHECK_NAME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, name, fname, STR_TERMINATE_ASCII); + CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, file_id, internal_info, internal_information, file_id); + + CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, file_id, internal_info, internal_information, file_id); + +done: + smb2_util_close(tree, h); + smb2_util_unlink(tree, fname); + talloc_free(mem_ctx); + + return ret; +} + + +struct multiple_result { + TALLOC_CTX *tctx; + int count; + union smb_search_data *list; +}; + +bool fill_result(void *private_data, + union smb_search_data *file, + int count, + uint8_t level, + enum smb_search_data_level data_level) +{ + int i; + const char *sname; + struct multiple_result *data = (struct multiple_result *)private_data; + + for (i=0; icount++; + data->list = talloc_realloc(data->tctx, + data->list, + union smb_search_data, + data->count); + data->list[data->count-1] = file[i]; + } + return true; +} + +enum continue_type {CONT_SINGLE, CONT_INDEX, CONT_RESTART}; + +static NTSTATUS multiple_smb2_search(struct smb2_tree *tree, + TALLOC_CTX *tctx, + const char *pattern, + uint8_t level, + enum smb_search_data_level data_level, + enum continue_type cont_type, + void *data, + struct smb2_handle *h) +{ + struct smb2_find f; + bool ret = true; + uint_t count = 0; + union smb_search_data *d; + NTSTATUS status; + struct multiple_result *result = (struct multiple_result *)data; + + ZERO_STRUCT(f); + f.in.file.handle = *h; + f.in.pattern = pattern; + f.in.max_response_size = 0x1000; + f.in.level = level; + + /* The search should start from the beginning everytime */ + f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART; + + do { + status = smb2_find_level(tree, tree, &f, &count, &d); + if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) + break; + CHECK_STATUS(status, NT_STATUS_OK); + if (!fill_result(result, d, count, level, data_level)) { + return NT_STATUS_UNSUCCESSFUL; + } + + /* + * After the first iteration is complete set the CONTINUE + * FLAGS appropriately + */ + switch (cont_type) { + case CONT_INDEX: + f.in.continue_flags = SMB2_CONTINUE_FLAG_INDEX; + break; + case CONT_SINGLE: + f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE; + break; + case CONT_RESTART: + default: + /* we should prevent staying in the loop forever */ + f.in.continue_flags = 0; + break; + } + } while (count != 0); +done: + return status; +} + + +static enum smb_search_data_level compare_data_level; +uint8_t level_sort; -/* - basic testing of directory listing with continue +static int search_compare(union smb_search_data *d1, + union smb_search_data *d2) +{ + const char *s1, *s2; + + s1 = extract_name(d1, level_sort, compare_data_level); + s2 = extract_name(d2, level_sort, compare_data_level); + return strcmp_safe(s1, s2); +} + +/* + basic testing of search calls using many files */ -bool torture_smb2_dir(struct torture_context *torture) +static bool test_many_files(struct torture_context *tctx, + struct smb2_tree *tree) { - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct smb2_tree *tree; + TALLOC_CTX *mem_ctx = talloc_new(tctx); + const int num_files = 700; + int i, t; + char *fname; bool ret = true; + NTSTATUS status; + struct multiple_result result; + struct smb2_create create; + struct smb2_handle h; + struct { + const char *name; + const char *cont_name; + uint8_t level; + enum smb_search_data_level data_level; + enum continue_type cont_type; + } search_types[] = { + {"SMB2_FIND_BOTH_DIRECTORY_INFO", "SINGLE", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_SINGLE}, + {"SMB2_FIND_BOTH_DIRECTORY_INFO", "INDEX", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_INDEX}, + {"SMB2_FIND_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_RESTART}, + {"SMB2_FIND_DIRECTORY_INFO", "SINGLE", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_SINGLE}, + {"SMB2_FIND_DIRECTORY_INFO", "INDEX", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_INDEX}, + {"SMB2_FIND_DIRECTORY_INFO", "RESTART", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_RESTART}, + {"SMB2_FIND_FULL_DIRECTORY_INFO", "SINGLE", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_SINGLE}, + {"SMB2_FIND_FULL_DIRECTORY_INFO", "INDEX", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_INDEX}, + {"SMB2_FIND_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_RESTART}, + {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "SINGLE", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_SINGLE}, + {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "INDEX", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_INDEX}, + {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_RESTART}, + {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "SINGLE", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_SINGLE}, + {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "INDEX", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_INDEX}, + {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_RESTART} + }; - if (!torture_smb2_connection(torture, &tree)) { + smb2_deltree(tree, DNAME); + status = torture_smb2_testdir(tree, DNAME, &h); + CHECK_STATUS(status, NT_STATUS_OK); + + torture_comment(tctx, "Testing with %d files\n", num_files); + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.create_disposition = NTCREATEX_DISP_CREATE; + + for (i=num_files-1;i>=0;i--) { + fname = talloc_asprintf(mem_ctx, DNAME "\\t%03d-%d.txt", i, i); + create.in.fname = talloc_asprintf(mem_ctx, "%s", fname); + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + smb2_util_close(tree, create.out.file.handle); + talloc_free(fname); + } + + for (t=0;tcount;i++) { + if (strcmp(name, + result->list[i].both_directory_info.name.s) == 0) { + break; + } + } + if (i == result->count) { + if (exist) { + printf("failed: '%s' should exist with attribute %s\n", + name, attrib_string(result->list, attrib)); + return false; + } + return true; + } + + if (!exist) { + printf("failed: '%s' should NOT exist (has attribute %s)\n", + name, attrib_string(result->list, + result->list[i].both_directory_info.attrib)); return false; } - ret &= torture_smb2_find_dir(tree); + if ((result->list[i].both_directory_info.attrib&0xFFF) != attrib) { + printf("failed: '%s' should have attribute 0x%x (has 0x%x)\n", + name, + attrib, result->list[i].both_directory_info.attrib); + return false; + } + return true; +} + +/* + test what happens when the directory is modified during a search +*/ +static bool test_modify_search(struct torture_context *tctx, + struct smb2_tree *tree) +{ + int num_files = 700; + struct multiple_result result; + union smb_setfileinfo sfinfo; + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_create create; + struct smb2_handle h; + struct smb2_find f; + union smb_search_data *d; + struct file_elem files[700] = {}; + NTSTATUS status; + bool ret = true; + int i; + uint_t count; + + smb2_deltree(tree, DNAME); + + status = torture_smb2_testdir(tree, DNAME, &h); + CHECK_STATUS(status, NT_STATUS_OK); + + printf("Creating %d files\n", num_files); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.create_disposition = NTCREATEX_DISP_CREATE; + + for (i = num_files-1; i >= 0; i--) { + files[i].name = talloc_asprintf(mem_ctx, "t%03d-%d.txt", i, i); + create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", + DNAME, files[i].name); + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + smb2_util_close(tree, create.out.file.handle); + } + + printf("pulling the first two files\n"); + ZERO_STRUCT(result); + result.tctx = talloc_new(tctx); + + ZERO_STRUCT(f); + f.in.file.handle = h; + f.in.pattern = "*"; + f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE; + f.in.max_response_size = 0x100; + f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO; + + do { + status = smb2_find_level(tree, tree, &f, &count, &d); + if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) + break; + CHECK_STATUS(status, NT_STATUS_OK); + if (!fill_result(&result, d, count, f.in.level, + RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO)) { + ret = false; + goto done; + } + }while(result.count < 2); + + printf("Changing attributes and deleting\n"); + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.create_disposition = NTCREATEX_DISP_CREATE; + + files[num_files].name = talloc_asprintf(mem_ctx, "T003-03.txt.2"); + create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", DNAME, + files[num_files].name); + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + smb2_util_close(tree, create.out.file.handle); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.create_disposition = NTCREATEX_DISP_CREATE; + + files[num_files + 1].name = talloc_asprintf(mem_ctx, "T013-13.txt.2"); + create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", DNAME, + files[num_files + 1].name); + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + smb2_util_close(tree, create.out.file.handle); + + files[num_files + 2].name = talloc_asprintf(mem_ctx, "T013-13.txt.3"); + status = smb2_create_complex_file(tree, DNAME "\\T013-13.txt.3", &h); + CHECK_STATUS(status, NT_STATUS_OK); + + smb2_util_unlink(tree, DNAME "\\T014-14.txt"); + smb2_util_setatr(tree, DNAME "\\T015-15.txt", FILE_ATTRIBUTE_HIDDEN); + smb2_util_setatr(tree, DNAME "\\T016-16.txt", FILE_ATTRIBUTE_NORMAL); + smb2_util_setatr(tree, DNAME "\\T017-17.txt", FILE_ATTRIBUTE_SYSTEM); + smb2_util_setatr(tree, DNAME "\\T018-18.txt", 0); + smb2_util_setatr(tree, DNAME "\\T039-39.txt", FILE_ATTRIBUTE_HIDDEN); + smb2_util_setatr(tree, DNAME "\\T000-0.txt", FILE_ATTRIBUTE_HIDDEN); + sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION; + sfinfo.generic.in.file.path = DNAME "\\T013-13.txt.3"; + sfinfo.disposition_info.in.delete_on_close = 1; + status = smb2_composite_setpathinfo(tree, &sfinfo); + CHECK_STATUS(status, NT_STATUS_OK); + + /* Reset the numfiles to include the new files and start the + * search from the beginning */ + num_files = num_files + 2; + f.in.pattern = "*"; + f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART; + result.count = 0; + + do { + status = smb2_find_level(tree, tree, &f, &count, &d); + if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) + break; + CHECK_STATUS(status, NT_STATUS_OK); + if (!fill_result(&result, d, count, f.in.level, + RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO)) { + ret = false; + goto done; + } + f.in.continue_flags = 0; + f.in.max_response_size = 4096; + } while (count != 0); + + + ret &= check_result(&result, "t039-39.txt", true, FILE_ATTRIBUTE_HIDDEN); + ret &= check_result(&result, "t000-0.txt", true, FILE_ATTRIBUTE_HIDDEN); + ret &= check_result(&result, "t014-14.txt", false, 0); + ret &= check_result(&result, "t015-15.txt", true, FILE_ATTRIBUTE_HIDDEN); + ret &= check_result(&result, "t016-16.txt", true, FILE_ATTRIBUTE_NORMAL); + ret &= check_result(&result, "t017-17.txt", true, FILE_ATTRIBUTE_SYSTEM); + ret &= check_result(&result, "t018-18.txt", true, FILE_ATTRIBUTE_ARCHIVE); + ret &= check_result(&result, "t019-19.txt", true, FILE_ATTRIBUTE_ARCHIVE); + ret &= check_result(&result, "T013-13.txt.2", true, FILE_ATTRIBUTE_ARCHIVE); + ret &= check_result(&result, "T003-3.txt.2", false, 0); + ret &= check_result(&result, "T013-13.txt.3", true, FILE_ATTRIBUTE_NORMAL); + + if (!ret) { + for (i=0;i 0) { + printf("non-alphabetical order at entry %d '%s' '%s'" + "\n", i, name1, name2); + torture_comment(tctx, + "Server does not produce sorted directory listings" + "(not an error)\n"); + goto done; + } + } + talloc_free(result.list); +done: + smb2_util_close(tree, h); + smb2_deltree(tree, DNAME); + talloc_free(mem_ctx); + + return ret; +} + +/* test the behavior of file_index field in the SMB2_FIND struct */ + +static bool test_file_index(struct torture_context *tctx, + struct smb2_tree *tree) +{ + TALLOC_CTX *mem_ctx = talloc_new(mem_ctx); + const int num_files = 100; + int resume_index = 4; + int i; + char *fname; + bool ret = true; + NTSTATUS status; + struct multiple_result result; + struct smb2_create create; + struct smb2_find f; + struct smb2_handle h; + union smb_search_data *d; + int count; + + smb2_deltree(tree, DNAME); + + status = torture_smb2_testdir(tree, DNAME, &h); + CHECK_STATUS(status, NT_STATUS_OK); + + printf("Testing the behavior of file_index flag\n"); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.create_disposition = NTCREATEX_DISP_CREATE; + for (i = num_files-1; i >= 0; i--) { + fname = talloc_asprintf(mem_ctx, DNAME "\\file%u.txt", i); + create.in.fname = fname; + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + talloc_free(fname); + smb2_util_close(tree, create.out.file.handle); + } + + ZERO_STRUCT(result); + result.tctx = tctx; + + ZERO_STRUCT(f); + f.in.file.handle = h; + f.in.pattern = "*"; + f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE; + f.in.max_response_size = 0x1000; + f.in.level = SMB2_FIND_FULL_DIRECTORY_INFO; + + do { + status = smb2_find_level(tree, tree, &f, &count, &d); + if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) + break; + CHECK_STATUS(status, NT_STATUS_OK); + if (!fill_result(&result, d, count, f.in.level, + RAW_SEARCH_DATA_FULL_DIRECTORY_INFO)) { + ret = false; + goto done; + } + } while(result.count < 10); + + if (result.list[0].full_directory_info.file_index == 0) { + torture_comment(tctx, + "Talking to a server that doesn't provide a " + "file index.\nWindows servers using NTFS do " + "not provide a file_index. Skipping test\n"); + goto done; + } else { + /* We are not talking to a Windows based server. Windows + * servers using NTFS do not provide a file_index. Windows + * server using FAT do provide a file index, however in both + * cases they do not honor a file index on a resume request. + * See MS-FSCC <62> and MS-SMB2 <54> for more information. */ + + /* Set the file_index flag to point to the fifth file from the + * previous enumeration and try to start the subsequent + * searches from that point */ + f.in.file_index = + result.list[resume_index].full_directory_info.file_index; + f.in.continue_flags = SMB2_CONTINUE_FLAG_INDEX; + + /* get the name of the next expected file */ + fname = talloc_asprintf(mem_ctx, DNAME "\\%s", + result.list[resume_index].full_directory_info.name.s); + + ZERO_STRUCT(result); + result.tctx = tctx; + status = smb2_find_level(tree, tree, &f, &count, &d); + if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) + goto done; + CHECK_STATUS(status, NT_STATUS_OK); + if (!fill_result(&result, d, count, f.in.level, + RAW_SEARCH_DATA_FULL_DIRECTORY_INFO)) { + ret = false; + goto done; + } + if (strcmp(fname, + result.list[0].full_directory_info.name.s)) { + printf("next expected file: %s but the server " + "returned %s\n", fname, + result.list[0].full_directory_info.name.s); + torture_comment(tctx, + "Not an error. Resuming using a file " + "index is an optional feature of the " + "protocol."); + goto done; + } + } +done: + smb2_util_close(tree, h); + smb2_deltree(tree, DNAME); + talloc_free(mem_ctx); + + return ret; +} + +/* + * Tests directory enumeration in a directory containing >1000 files with + * names of varying lengths. + */ +static bool test_large_files(struct torture_context *tctx, + struct smb2_tree *tree) +{ + TALLOC_CTX *mem_ctx = talloc_new(mem_ctx); + const int num_files = 2000; + int i, j = 1, retry_count = 0; + struct file_elem files[2000] = {}; + bool ret = true; + NTSTATUS status; + struct smb2_create create; + struct smb2_find f; + struct smb2_handle h; + union smb_search_data *d; + int count, file_count = 0; + + torture_comment(tctx, + "Testing directory enumeration in a directory with >1000 files\n"); + + smb2_deltree(tree, DNAME); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_DIR_ALL; + create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; + create.in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE; + create.in.create_disposition = NTCREATEX_DISP_CREATE; + create.in.fname = DNAME; + + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + h = create.out.file.handle; + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.create_disposition = NTCREATEX_DISP_CREATE; + + for (i = 0; i < num_files; i++) { + files[i].name = generate_random_str(tctx, j); + create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", + DNAME, files[i].name); + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + smb2_util_close(tree, create.out.file.handle); + retry_count = 0; + if (i%9 == 0) + j = j + 1; + } + + ZERO_STRUCT(f); + f.in.file.handle = h; + f.in.pattern = "*"; + f.in.max_response_size = 0x100; + f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO; + + do { + status = smb2_find_level(tree, tree, &f, &count, &d); + if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) + break; + CHECK_STATUS(status, NT_STATUS_OK); + + for (i = 0; i < count; i++) { + bool expected; + const char *found = d[i].both_directory_info.name.s; + + if (!strcmp(found, ".") || !strcmp(found, "..")) + continue; + + expected = false; + for (j = 0; j < 2000; j++) { + if (!strcmp(files[j].name, found)) { + files[j].found = true; + expected = true; + break; + } + } + + if (expected) + continue; + + torture_result(tctx, TORTURE_FAIL, + "(%s): didn't expect %s\n", + __location__, found); + ret = false; + goto done; + } + file_count = file_count + i; + f.in.continue_flags = 0; + f.in.max_response_size = 4096; + } while (count != 0); + + CHECK_VALUE(file_count, num_files + 2); + + for (i = 0; i < num_files; i++) { + if (files[j].found) + continue; + + torture_result(tctx, TORTURE_FAIL, + "(%s): expected to find %s, but didn't\n", + __location__, files[j].name); + ret = false; + goto done; + } +done: + smb2_util_close(tree, h); + smb2_deltree(tree, DNAME); + talloc_free(mem_ctx); + + return ret; +} + +struct torture_suite *torture_smb2_dir_init(void) +{ + struct torture_suite *suite = + torture_suite_create(talloc_autofree_context(), "DIR"); + + torture_suite_add_1smb2_test(suite, "FIND", test_find); + torture_suite_add_1smb2_test(suite, "FIXED", test_fixed); + torture_suite_add_1smb2_test(suite, "ONE", test_one_file); + torture_suite_add_1smb2_test(suite, "MANY", test_many_files); + torture_suite_add_1smb2_test(suite, "MODIFY", test_modify_search); + torture_suite_add_1smb2_test(suite, "SORTED", test_sorted); + torture_suite_add_1smb2_test(suite, "FILE-INDEX", test_file_index); + torture_suite_add_1smb2_test(suite, "LARGE-FILES", test_large_files); + suite->description = talloc_strdup(suite, "SMB2-DIR tests"); + + return suite; +} diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c index a5730a7eb3..9766620867 100644 --- a/source4/torture/smb2/smb2.c +++ b/source4/torture/smb2/smb2.c @@ -141,6 +141,7 @@ NTSTATUS torture_smb2_init(void) torture_suite_add_simple_test(suite, "NOTIFY", torture_smb2_notify); torture_suite_add_suite(suite, torture_smb2_durable_open_init()); torture_suite_add_1smb2_test(suite, "OPLOCK-BATCH1", torture_smb2_oplock_batch1); + torture_suite_add_suite(suite, torture_smb2_dir_init()); torture_suite_add_suite(suite, torture_smb2_lease_init()); torture_suite_add_suite(suite, torture_smb2_compound_init()); -- cgit From e84d5bb02d113ae54172755ea284e7f22b677a7b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 15 Jul 2009 01:22:32 +0200 Subject: s4-selftest: ok, s4 cant print. add RPC-SPOOLSS-PRINTER to knownfail for now. Guenther --- source4/selftest/knownfail | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/selftest/knownfail b/source4/selftest/knownfail index 91180418b8..68d406ab9b 100644 --- a/source4/selftest/knownfail +++ b/source4/selftest/knownfail @@ -40,6 +40,7 @@ rpc.netlogon.*.DatabaseRedo rpc.netlogon.*.ServerGetTrustInfo samba4.rpc.samr.passwords.pwdlastset # Not provided by Samba 4 yet samba4.rpc.samr.users.privileges +samba4.rpc.spoolss.printer # Not provided by Samba 4 yet base.charset.*.Testing partial surrogate .*net.api.delshare.* # DelShare isn't implemented yet rap.*netservergetinfo -- cgit From 7be1d727a31b34debbcf8faa1e0bea911112d145 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Jul 2009 16:42:21 -0700 Subject: When tallocing a memory block for the state in a tevent_req struct, ensure it's zeroed out. Vl & Metze please check. Jeremy. --- lib/tevent/tevent_req.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index 541f93f99c..1ddf9ef155 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -109,6 +109,7 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, talloc_free(req); return NULL; } + memset(data, '\0', data_size); talloc_set_name_const(data, type); req->data = data; -- cgit From 5927ca7067a0ead65c00042a62545b0d940f2b2a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Jul 2009 16:54:01 -0700 Subject: Change to talloc_zero_size instead of extra memset. Jeremy. --- lib/tevent/tevent_req.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index 1ddf9ef155..0feabb5f1f 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -104,12 +104,11 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, return NULL; } - data = talloc_size(req, data_size); + data = talloc_zero_size(req, data_size); if (data == NULL) { talloc_free(req); return NULL; } - memset(data, '\0', data_size); talloc_set_name_const(data, type); req->data = data; -- cgit From 8cb44830e0356804e21d9973382e0070f20b15be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 10:49:41 +0200 Subject: torture/smb2: fix crash bugs in the new SMB2-DIR tests metze --- source4/torture/smb2/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/torture/smb2/dir.c b/source4/torture/smb2/dir.c index 79672ef03a..e090c31ec9 100644 --- a/source4/torture/smb2/dir.c +++ b/source4/torture/smb2/dir.c @@ -1083,7 +1083,7 @@ done: static bool test_file_index(struct torture_context *tctx, struct smb2_tree *tree) { - TALLOC_CTX *mem_ctx = talloc_new(mem_ctx); + TALLOC_CTX *mem_ctx = talloc_new(tctx); const int num_files = 100; int resume_index = 4; int i; @@ -1201,7 +1201,7 @@ done: static bool test_large_files(struct torture_context *tctx, struct smb2_tree *tree) { - TALLOC_CTX *mem_ctx = talloc_new(mem_ctx); + TALLOC_CTX *mem_ctx = talloc_new(tctx); const int num_files = 2000; int i, j = 1, retry_count = 0; struct file_elem files[2000] = {}; -- cgit From 565046891f9f7725b5d93eefbc3be5b9c62176fd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 10:54:33 +0200 Subject: Replace ASSERTs in gencache with "return false" It's a bit strong to panic here I think. --- source3/lib/gencache.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 7f133f20b0..5497c4c240 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -115,8 +115,9 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) TDB_DATA databuf; char* valstr = NULL; - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr && value); + if ((keystr == NULL) || (value == NULL)) { + return false; + } if (!gencache_init()) return False; @@ -149,8 +150,9 @@ bool gencache_del(const char *keystr) { int ret; - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr); + if (keystr == NULL) { + return false; + } if (!gencache_init()) return False; @@ -180,8 +182,9 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout) time_t t; char *endptr; - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr); + if (keystr == NULL) { + return false; + } if (!gencache_init()) { return False; @@ -256,8 +259,9 @@ bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired) int buflen = 0, len = 0, blob_len = 0; unsigned char *blob_buf = NULL; - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr); + if (keystr == NULL) { + return false; + } if (!gencache_init()) { return False; @@ -333,8 +337,9 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t ti unsigned char *buf = NULL; int len = 0, buflen = 0; - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr && blob); + if ((keystr == NULL) || (blob == NULL)) { + return false; + } if (!gencache_init()) { return False; @@ -465,8 +470,9 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time { struct gencache_iterate_state state; - /* fail completely if get null pointers passed */ - SMB_ASSERT(fn && keystr_pattern); + if ((fn == NULL) || (keystr_pattern == NULL)) { + return; + } if (!gencache_init()) return; -- cgit From 3e965d017d243f0a99e7838e6c92c37df270486c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 11:00:24 +0200 Subject: TDB_CONTEXT -> "struct tdb_context" --- source3/lib/gencache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 5497c4c240..0e099f0dd0 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -31,7 +31,7 @@ #define BLOB_TYPE "DATA_BLOB" #define BLOB_TYPE_LEN 9 -static TDB_CONTEXT *cache; +static struct tdb_context *cache; /** * @file gencache.c -- cgit From e5a34b2533720ebb9181c0edebad6774ceeff189 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 12:03:35 +0200 Subject: Remove gencache_[un]lock_key --- source3/include/proto.h | 2 -- source3/lib/gencache.c | 25 ------------------------- source3/libsmb/dsgetdcname.c | 6 ------ 3 files changed, 33 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 0dd1e98c86..52ca7826ed 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -524,8 +524,6 @@ bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired); bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout); void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr), void* data, const char* keystr_pattern); -int gencache_lock_entry( const char *key ); -void gencache_unlock_entry( const char *key ); /* The following definitions come from lib/interface.c */ diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 0e099f0dd0..c94fb78541 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -483,28 +483,3 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time state.priv = data; tdb_traverse(cache, gencache_iterate_fn, &state); } - -/******************************************************************** - lock a key -********************************************************************/ - -int gencache_lock_entry( const char *key ) -{ - if (!gencache_init()) - return -1; - - return tdb_lock_bystring(cache, key); -} - -/******************************************************************** - unlock a key -********************************************************************/ - -void gencache_unlock_entry( const char *key ) -{ - if (!gencache_init()) - return; - - tdb_unlock_bystring(cache, key); - return; -} diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index fb87b4dc9a..8dee6926d2 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -171,14 +171,8 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL; - if (gencache_lock_entry(key) != 0) { - return NT_STATUS_LOCK_NOT_GRANTED; - } - ret = gencache_set_data_blob(key, blob, expire_time); - gencache_unlock_entry(key); - return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } -- cgit From d936d1bd84e130aaff1de64cb1ecbd1f936dd9c4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 12:12:30 +0200 Subject: Fix some nonempty blank lines --- source3/libsmb/trustdom_cache.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 6755de3814..d891c0768e 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -4,17 +4,17 @@ Trusted domain names cache on top of gencache. Copyright (C) Rafal Szczesniak 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 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 . */ @@ -38,7 +38,6 @@ * list of trusted domains **/ - /** * Initialise trustdom name caching system. Call gencache * initialisation routine to perform necessary activities. @@ -46,7 +45,7 @@ * @return true upon successful cache initialisation or * false if cache init failed **/ - + bool trustdom_cache_enable(void) { /* Init trustdom cache by calling gencache initialisation */ @@ -66,7 +65,7 @@ bool trustdom_cache_enable(void) * @return true upon successful cache close or * false if it failed **/ - + bool trustdom_cache_shutdown(void) { /* Close trustdom cache by calling gencache shutdown */ @@ -74,7 +73,7 @@ bool trustdom_cache_shutdown(void) DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n")); return False; } - + return True; } @@ -91,7 +90,7 @@ static char* trustdom_cache_key(const char* name) { char* keystr = NULL; asprintf_strupper_m(&keystr, TDOMKEY_FMT, name); - + return keystr; } @@ -160,7 +159,7 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, * @return true if entry is found or * false if has expired/doesn't exist **/ - + bool trustdom_cache_fetch(const char* name, DOM_SID* sid) { char *key = NULL, *value = NULL; @@ -169,7 +168,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) /* init the cache */ if (!gencache_init()) return False; - + /* exit now if null pointers were passed as they're required further */ if (!sid) return False; @@ -178,7 +177,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) key = trustdom_cache_key(name); if (!key) return False; - + if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("no entry for trusted domain %s found.\n", name)); SAFE_FREE(key); @@ -194,7 +193,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) SAFE_FREE(value); return False; } - + SAFE_FREE(value); return True; } @@ -213,7 +212,7 @@ uint32 trustdom_cache_fetch_timestamp( void ) /* init the cache */ if (!gencache_init()) return False; - + if (!gencache_get(TDOMTSKEY, &value, &timeout)) { DEBUG(5, ("no timestamp for trusted domain cache located.\n")); SAFE_FREE(value); @@ -221,7 +220,7 @@ uint32 trustdom_cache_fetch_timestamp( void ) } timestamp = atoi(value); - + SAFE_FREE(value); return timestamp; } @@ -237,9 +236,9 @@ bool trustdom_cache_store_timestamp( uint32 t, time_t timeout ) /* init the cache */ if (!gencache_init()) return False; - + fstr_sprintf(value, "%d", t ); - + if (!gencache_set(TDOMTSKEY, value, timeout)) { DEBUG(5, ("failed to set timestamp for trustdom_cache\n")); return False; @@ -294,13 +293,13 @@ void update_trustdom_cache( void ) TALLOC_CTX *mem_ctx = NULL; time_t now = time(NULL); int i; - + /* get the timestamp. We have to initialise it if the last timestamp == 0 */ if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 ) trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL); time_diff = (int) (now - last_check); - + if ( (time_diff > 0) && (time_diff < TRUSTDOM_UPDATE_INTERVAL) ) { DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n")); return; @@ -310,14 +309,14 @@ void update_trustdom_cache( void ) smbd from blocking all other smbd daemons while we enumerate the trusted domains */ trustdom_cache_store_timestamp(now, now+TRUSTDOM_UPDATE_INTERVAL); - + if ( !(mem_ctx = talloc_init("update_trustdom_cache")) ) { DEBUG(0,("update_trustdom_cache: talloc_init() failed!\n")); goto done; } /* get the domains and store them */ - + if ( enumerate_domain_trusts(mem_ctx, lp_workgroup(), &domain_names, &num_domains, &dom_sids)) { for ( i=0; i Date: Fri, 10 Jul 2009 12:24:56 +0200 Subject: Remove gencache_init/shutdown gencache_get/set/del/iterate call gencache_init() internally anyway. And we've been very lazy calling gencache_shutdown, so this seems not really required. --- source3/include/proto.h | 2 -- source3/lib/gencache.c | 21 +-------------------- source3/lib/netapi/netapi.c | 1 - source3/libads/dns.c | 8 -------- source3/libsmb/dsgetdcname.c | 12 ------------ source3/libsmb/libsmb_context.c | 1 - source3/libsmb/namecache.c | 34 ---------------------------------- source3/libsmb/namequery.c | 12 ------------ source3/libsmb/trustdom_cache.c | 34 ---------------------------------- source3/torture/torture.c | 16 ---------------- source3/utils/net_cache.c | 4 ---- 11 files changed, 1 insertion(+), 144 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 52ca7826ed..23bd22aadc 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -515,8 +515,6 @@ void pull_file_id_24(char *buf, struct file_id *id); /* The following definitions come from lib/gencache.c */ -bool gencache_init(void); -bool gencache_shutdown(void); bool gencache_set(const char *keystr, const char *value, time_t timeout); bool gencache_del(const char *keystr); bool gencache_get(const char *keystr, char **valstr, time_t *timeout); diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index c94fb78541..06eb29345b 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -49,7 +49,7 @@ static struct tdb_context *cache; * false on failure **/ -bool gencache_init(void) +static bool gencache_init(void) { char* cache_fname = NULL; @@ -78,25 +78,6 @@ bool gencache_init(void) } -/** - * Cache shutdown function. Closes opened cache tdb file. - * - * @return true on successful closing the cache or - * false on failure during cache shutdown - **/ - -bool gencache_shutdown(void) -{ - int ret; - /* tdb_close routine returns -1 on error */ - if (!cache) return False; - DEBUG(5, ("Closing cache file\n")); - ret = tdb_close(cache); - cache = NULL; - return ret != -1; -} - - /** * Set an entry in the cache file. If there's no such * one, then add it. diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 2f8474b37f..e80879a1d2 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -170,7 +170,6 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) gfree_charcnv(); gfree_interfaces(); - gencache_shutdown(); secrets_shutdown(); TALLOC_FREE(ctx); diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 3a9e849668..5cf768de67 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -754,10 +754,6 @@ bool sitename_store(const char *realm, const char *sitename) bool ret = False; char *key; - if (!gencache_init()) { - return False; - } - if (!realm || (strlen(realm) == 0)) { DEBUG(0,("sitename_store: no realm\n")); return False; @@ -795,10 +791,6 @@ char *sitename_fetch(const char *realm) const char *query_realm; char *key; - if (!gencache_init()) { - return NULL; - } - if (!realm || (strlen(realm) == 0)) { query_realm = lp_realm(); } else { diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 8dee6926d2..9552ad1f22 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -133,10 +133,6 @@ static NTSTATUS dsgetdcname_cache_delete(TALLOC_CTX *mem_ctx, { char *key; - if (!gencache_init()) { - return NT_STATUS_INTERNAL_DB_ERROR; - } - key = dsgetdcname_cache_key(mem_ctx, domain_name); if (!key) { return NT_STATUS_NO_MEMORY; @@ -160,10 +156,6 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, char *key; bool ret = false; - if (!gencache_init()) { - return NT_STATUS_INTERNAL_DB_ERROR; - } - key = dsgetdcname_cache_key(mem_ctx, domain_name); if (!key) { return NT_STATUS_NO_MEMORY; @@ -357,10 +349,6 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, struct NETLOGON_SAM_LOGON_RESPONSE_EX r; NTSTATUS status; - if (!gencache_init()) { - return NT_STATUS_INTERNAL_DB_ERROR; - } - key = dsgetdcname_cache_key(mem_ctx, domain_name); if (!key) { return NT_STATUS_NO_MEMORY; diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 98885876b3..8b22ee5023 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -123,7 +123,6 @@ SMBC_module_init(void * punused) static void SMBC_module_terminate(void) { - gencache_shutdown(); secrets_shutdown(); gfree_all(); SMBC_initialized = false; diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index d3230cffef..dcfc609dcd 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -45,14 +45,6 @@ bool namecache_enable(void) return False; } - /* Init namecache by calling gencache initialisation */ - - if (!gencache_init()) { - DEBUG(2, ("namecache_enable: " - "Couldn't initialise namecache on top of gencache.\n")); - return False; - } - /* I leave it for now, though I don't think we really * need this (mimir, 27.09.2002) */ DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d " @@ -102,14 +94,6 @@ bool namecache_store(const char *name, int i; bool ret; - /* - * we use gecache call to avoid annoying debug messages about - * initialised namecache again and again... - */ - if (!gencache_init()) { - return False; - } - if (name_type > 255) { return False; /* Don't store non-real name types. */ } @@ -186,10 +170,6 @@ bool namecache_fetch(const char *name, return False; } - if (!gencache_init()) { - return False; - } - if (name_type > 255) { return False; /* Don't fetch non-real name types. */ } @@ -233,9 +213,6 @@ bool namecache_delete(const char *name, int name_type) bool ret; char *key; - if (!gencache_init()) - return False; - if (name_type > 255) { return False; /* Don't fetch non-real name types. */ } @@ -274,10 +251,6 @@ static void flush_netbios_name(const char *key, void namecache_flush(void) { - if (!gencache_init()) { - return; - } - /* * iterate through each NBT cache's entry and flush it * by flush_netbios_name function @@ -312,10 +285,6 @@ bool namecache_status_store(const char *keyname, int keyname_type, time_t expiry; bool ret; - if (!gencache_init()) { - return False; - } - key = namecache_status_record_key(keyname, keyname_type, name_type, keyip); if (!key) @@ -348,9 +317,6 @@ bool namecache_status_fetch(const char *keyname, char *value = NULL; time_t timeout; - if (!gencache_init()) - return False; - key = namecache_status_record_key(keyname, keyname_type, name_type, keyip); if (!key) diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 50fb9f1620..05143270b9 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -76,9 +76,6 @@ bool saf_store( const char *domain, const char *servername ) return False; } - if ( !gencache_init() ) - return False; - key = saf_key( domain ); expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL); @@ -108,9 +105,6 @@ bool saf_join_store( const char *domain, const char *servername ) return False; } - if ( !gencache_init() ) - return False; - key = saf_join_key( domain ); expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL); @@ -134,9 +128,6 @@ bool saf_delete( const char *domain ) return False; } - if ( !gencache_init() ) - return False; - key = saf_join_key(domain); ret = gencache_del(key); SAFE_FREE(key); @@ -171,9 +162,6 @@ char *saf_fetch( const char *domain ) return NULL; } - if ( !gencache_init() ) - return False; - key = saf_join_key( domain ); ret = gencache_get( key, &server, &timeout ); diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index d891c0768e..eb52b3588d 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -48,12 +48,6 @@ bool trustdom_cache_enable(void) { - /* Init trustdom cache by calling gencache initialisation */ - if (!gencache_init()) { - DEBUG(2, ("trustdomcache_enable: Couldn't initialise trustdom cache on top of gencache.\n")); - return False; - } - return True; } @@ -68,12 +62,6 @@ bool trustdom_cache_enable(void) bool trustdom_cache_shutdown(void) { - /* Close trustdom cache by calling gencache shutdown */ - if (!gencache_shutdown()) { - DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n")); - return False; - } - return True; } @@ -114,13 +102,6 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, fstring sid_string; bool ret; - /* - * we use gecache call to avoid annoying debug messages - * about initialised trustdom - */ - if (!gencache_init()) - return False; - DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n", sid_string_dbg(sid), name)); @@ -165,10 +146,6 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) char *key = NULL, *value = NULL; time_t timeout; - /* init the cache */ - if (!gencache_init()) - return False; - /* exit now if null pointers were passed as they're required further */ if (!sid) return False; @@ -209,10 +186,6 @@ uint32 trustdom_cache_fetch_timestamp( void ) time_t timeout; uint32 timestamp; - /* init the cache */ - if (!gencache_init()) - return False; - if (!gencache_get(TDOMTSKEY, &value, &timeout)) { DEBUG(5, ("no timestamp for trusted domain cache located.\n")); SAFE_FREE(value); @@ -233,10 +206,6 @@ bool trustdom_cache_store_timestamp( uint32 t, time_t timeout ) { fstring value; - /* init the cache */ - if (!gencache_init()) - return False; - fstr_sprintf(value, "%d", t ); if (!gencache_set(TDOMTSKEY, value, timeout)) { @@ -267,9 +236,6 @@ static void flush_trustdom_name(const char* key, const char *value, time_t timeo void trustdom_cache_flush(void) { - if (!gencache_init()) - return; - /* * iterate through each TDOM cache's entry and flush it * by flush_trustdom_name function diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 8cebc2adcc..e3c4084e0c 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -5800,11 +5800,6 @@ static bool run_local_gencache(int dummy) time_t tm; DATA_BLOB blob; - if (!gencache_init()) { - d_printf("%s: gencache_init() failed\n", __location__); - return False; - } - if (!gencache_set("foo", "bar", time(NULL) + 1000)) { d_printf("%s: gencache_set() failed\n", __location__); return False; @@ -5878,17 +5873,6 @@ static bool run_local_gencache(int dummy) return False; } - if (!gencache_shutdown()) { - d_printf("%s: gencache_shutdown() failed\n", __location__); - return False; - } - - if (gencache_shutdown()) { - d_printf("%s: second gencache_shutdown() succeeded\n", - __location__); - return False; - } - return True; } diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c index 5e7db38515..74d8d29b4b 100644 --- a/source3/utils/net_cache.c +++ b/source3/utils/net_cache.c @@ -171,12 +171,10 @@ static int net_cache_add(struct net_context *c, int argc, const char **argv) if (gencache_set(keystr, datastr, timeout)) { d_printf("New cache entry stored successfully.\n"); - gencache_shutdown(); return 0; } d_fprintf(stderr, "Entry couldn't be added. Perhaps there's already such a key.\n"); - gencache_shutdown(); return -1; } @@ -275,7 +273,6 @@ static int net_cache_list(struct net_context *c, int argc, const char **argv) return 0; } gencache_iterate(print_cache_entry, NULL, pattern); - gencache_shutdown(); return 0; } @@ -297,7 +294,6 @@ static int net_cache_flush(struct net_context *c, int argc, const char **argv) return 0; } gencache_iterate(delete_cache_entry, NULL, pattern); - gencache_shutdown(); return 0; } -- cgit From ed87594e5fd3251f9cb3beaca06c8eee1dcd4ed2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 13 Jul 2009 17:03:52 +0200 Subject: Add tdb_data_cmp --- source3/include/util_tdb.h | 2 ++ source3/lib/util_tdb.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/source3/include/util_tdb.h b/source3/include/util_tdb.h index c79436434f..80b95921d7 100644 --- a/source3/include/util_tdb.h +++ b/source3/include/util_tdb.h @@ -59,4 +59,6 @@ struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err); +int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2); + #endif /* __TDBUTIL_H__ */ diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c index 78fa7cd0a1..5b3d94dabe 100644 --- a/source3/lib/util_tdb.c +++ b/source3/lib/util_tdb.c @@ -630,3 +630,22 @@ NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err) return NT_STATUS_INTERNAL_ERROR; } + +int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2) +{ + int ret; + if (t1.dptr == NULL && t2.dptr != NULL) { + return -1; + } + if (t1.dptr != NULL && t2.dptr == NULL) { + return 1; + } + if (t1.dptr == t2.dptr) { + return t1.dsize - t2.dsize; + } + ret = memcmp(t1.dptr, t2.dptr, MIN(t1.dsize, t2.dsize)); + if (ret == 0) { + return t1.dsize - t2.dsize; + } + return ret; +} -- cgit From 8a17cd810fa6cbe7b11139ff0f6f24e7bacd318b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 13 Jul 2009 17:04:29 +0200 Subject: Make gencache more stable This provides a compromise between stability and performance: gencache is a persistent database these days that for performance reasons can not use tdb transactions for all writes. This patch splits up gencache into gencache.tdb and gencache_notrans.tdb. gencache_notrans is used with CLEAR_IF_FIRST, writes to it don't use transactions. By default every 5 minutes and when a program exits, all entries from _notrans.tdb are transferred to gencache.tdb in one transaction. --- source3/include/proto.h | 1 + source3/lib/gencache.c | 283 +++++++++++++++++++++++++++++++++++++++++--- source3/nmbd/nmbd.c | 2 + source3/smbd/server.c | 1 + source3/utils/net.c | 2 + source3/utils/net_cache.c | 23 ++++ source3/winbindd/winbindd.c | 2 + 7 files changed, 299 insertions(+), 15 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 23bd22aadc..dd49e53338 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -519,6 +519,7 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout); bool gencache_del(const char *keystr); bool gencache_get(const char *keystr, char **valstr, time_t *timeout); bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired); +bool gencache_stabilize(void); bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout); void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr), void* data, const char* keystr_pattern); diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 06eb29345b..73f433c1c0 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -32,6 +32,7 @@ #define BLOB_TYPE_LEN 9 static struct tdb_context *cache; +static struct tdb_context *cache_notrans; /** * @file gencache.c @@ -52,6 +53,7 @@ static struct tdb_context *cache; static bool gencache_init(void) { char* cache_fname = NULL; + int open_flags = O_RDWR|O_CREAT; /* skip file open if it's already opened */ if (cache) return True; @@ -60,11 +62,12 @@ static bool gencache_init(void) DEBUG(5, ("Opening cache file at %s\n", cache_fname)); - cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, - O_RDWR|O_CREAT, 0644); + cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, open_flags, 0644); if (!cache && (errno == EACCES)) { - cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDONLY, 0644); + open_flags = O_RDONLY; + cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, open_flags, + 0644); if (cache) { DEBUG(5, ("gencache_init: Opening cache file %s read-only.\n", cache_fname)); } @@ -74,9 +77,30 @@ static bool gencache_init(void) DEBUG(5, ("Attempt to open gencache.tdb has failed.\n")); return False; } + + cache_fname = lock_path("gencache_notrans.tdb"); + + DEBUG(5, ("Opening cache file at %s\n", cache_fname)); + + cache_notrans = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST, + open_flags, 0644); + if (cache_notrans == NULL) { + DEBUG(5, ("Opening %s failed: %s\n", cache_fname, + strerror(errno))); + tdb_close(cache); + return false; + } + return True; } +static TDB_DATA last_stabilize_key(void) +{ + TDB_DATA result; + result.dptr = (uint8_t *)"@LAST_STABILIZED"; + result.dsize = 17; + return result; +} /** * Set an entry in the cache file. If there's no such @@ -95,6 +119,13 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) int ret; TDB_DATA databuf; char* valstr = NULL; + time_t last_stabilize; + + if (tdb_data_cmp(string_term_tdb_data(keystr), + last_stabilize_key()) == 0) { + DEBUG(10, ("Can't store %s as a key\n", keystr)); + return false; + } if ((keystr == NULL) || (value == NULL)) { return false; @@ -112,9 +143,31 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) (int)(timeout - time(NULL)), timeout > time(NULL) ? "ahead" : "in the past")); - ret = tdb_store_bystring(cache, keystr, databuf, 0); + ret = tdb_store_bystring(cache_notrans, keystr, databuf, 0); SAFE_FREE(valstr); + if (ret != 0) { + return false; + } + + /* + * Every 5 minutes, call gencache_stabilize() to not let grow + * gencache_notrans.tdb too large. + */ + + last_stabilize = 0; + databuf = tdb_fetch(cache_notrans, last_stabilize_key()); + if ((databuf.dptr != NULL) + && (databuf.dptr[databuf.dsize-1] == '\0')) { + last_stabilize = atoi((char *)databuf.dptr); + SAFE_FREE(databuf.dptr); + } + if ((last_stabilize + + lp_parm_int(-1, "gencache", "stabilize_interval", 300)) + < time(NULL)) { + gencache_stabilize(); + } + return ret == 0; } @@ -129,7 +182,9 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) bool gencache_del(const char *keystr) { - int ret; + bool exists; + bool ret = false; + char *value; if (keystr == NULL) { return false; @@ -138,11 +193,46 @@ bool gencache_del(const char *keystr) if (!gencache_init()) return False; DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr)); - ret = tdb_delete_bystring(cache, keystr); - return ret == 0; + if (tdb_lock_bystring(cache_notrans, keystr) == -1) { + DEBUG(5, ("Could not lock key for %s\n", keystr)); + return false; + } + + /* + * We delete an element by setting its timeout to 0. This way we don't + * have to do a transaction on gencache.tdb every time we delete an + * element. + */ + + exists = gencache_get(keystr, &value, NULL); + if (exists) { + SAFE_FREE(value); + ret = gencache_set(keystr, "", 0); + } + tdb_unlock_bystring(cache_notrans, keystr); + return ret; } +static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr) +{ + time_t res; + char *endptr; + + res = strtol(val, &endptr, 10); + + if ((endptr == NULL) || (*endptr != '/')) { + DEBUG(2, ("Invalid gencache data format: %s\n", val)); + return false; + } + if (pres != NULL) { + *pres = res; + } + if (pendptr != NULL) { + *pendptr = endptr; + } + return true; +} /** * Get existing entry from the cache file. @@ -167,22 +257,29 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout) return false; } + if (tdb_data_cmp(string_term_tdb_data(keystr), + last_stabilize_key()) == 0) { + DEBUG(10, ("Can't get %s as a key\n", keystr)); + return false; + } + if (!gencache_init()) { return False; } - databuf = tdb_fetch_bystring(cache, keystr); + databuf = tdb_fetch_bystring(cache_notrans, keystr); if (databuf.dptr == NULL) { - DEBUG(10, ("Cache entry with key = %s couldn't be found\n", + databuf = tdb_fetch_bystring(cache, keystr); + } + + if (databuf.dptr == NULL) { + DEBUG(10, ("Cache entry with key = %s couldn't be found \n", keystr)); return False; } - t = strtol((const char *)databuf.dptr, &endptr, 10); - - if ((endptr == NULL) || (*endptr != '/')) { - DEBUG(2, ("Invalid gencache data format: %s\n", databuf.dptr)); + if (!gencache_pull_timeout((char *)databuf.dptr, &t, &endptr)) { SAFE_FREE(databuf.dptr); return False; } @@ -191,10 +288,21 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout) "timeout = %s", t > time(NULL) ? "valid" : "expired", keystr, endptr+1, ctime(&t))); + if (t == 0) { + /* Deleted */ + SAFE_FREE(databuf.dptr); + return False; + } + if (t <= time(NULL)) { - /* We're expired, delete the entry */ - tdb_delete_bystring(cache, keystr); + /* + * We're expired, delete the entry. We can't use gencache_del + * here, because that uses gencache_get_data_blob for checking + * the existence of a record. We know the thing exists and + * directly store an empty value with 0 timeout. + */ + gencache_set(keystr, "", 0); SAFE_FREE(databuf.dptr); return False; @@ -218,6 +326,137 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout) return True; } +struct stabilize_state { + bool written; + bool error; +}; +static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val, + void *priv); + +/** + * Stabilize gencache + * + * Migrate the clear-if-first gencache data to the stable, + * transaction-based gencache.tdb + */ + +bool gencache_stabilize(void) +{ + struct stabilize_state state; + int res; + char *now; + + if (!gencache_init()) { + return false; + } + + res = tdb_transaction_start(cache); + if (res == -1) { + DEBUG(10, ("Could not start transaction on gencache.tdb: " + "%s\n", tdb_errorstr(cache))); + return false; + } + res = tdb_transaction_start(cache_notrans); + if (res == -1) { + tdb_transaction_cancel(cache); + DEBUG(10, ("Could not start transaction on " + "gencache_notrans.tdb: %s\n", + tdb_errorstr(cache_notrans))); + return false; + } + + state.error = false; + state.written = false; + + res = tdb_traverse(cache_notrans, stabilize_fn, &state); + if ((res == -1) || state.error) { + if ((tdb_transaction_cancel(cache_notrans) == -1) + || (tdb_transaction_cancel(cache) == -1)) { + smb_panic("tdb_transaction_cancel failed\n"); + } + return false; + } + + if (!state.written) { + if ((tdb_transaction_cancel(cache_notrans) == -1) + || (tdb_transaction_cancel(cache) == -1)) { + smb_panic("tdb_transaction_cancel failed\n"); + } + return true; + } + + res = tdb_transaction_commit(cache); + if (res == -1) { + DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: " + "%s\n", tdb_errorstr(cache))); + if (tdb_transaction_cancel(cache_notrans) == -1) { + smb_panic("tdb_transaction_cancel failed\n"); + } + return false; + } + + res = tdb_transaction_commit(cache_notrans); + if (res == -1) { + DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: " + "%s\n", tdb_errorstr(cache))); + return false; + } + + now = talloc_asprintf(talloc_tos(), "%d", (int)time(NULL)); + if (now != NULL) { + tdb_store(cache_notrans, last_stabilize_key(), + string_term_tdb_data(now), 0); + TALLOC_FREE(now); + } + + return true; +} + +static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val, + void *priv) +{ + struct stabilize_state *state = (struct stabilize_state *)priv; + int res; + time_t timeout; + + if (tdb_data_cmp(key, last_stabilize_key()) == 0) { + return 0; + } + + if (!gencache_pull_timeout((char *)val.dptr, &timeout, NULL)) { + DEBUG(10, ("Ignoring invalid entry\n")); + return 0; + } + if ((timeout < time(NULL)) || (val.dsize == 0)) { + res = tdb_delete(cache, key); + if ((res == -1) && (tdb_error(cache) == TDB_ERR_NOEXIST)) { + res = 0; + } else { + state->written = true; + } + } else { + res = tdb_store(cache, key, val, 0); + if (res == 0) { + state->written = true; + } + } + + if (res == -1) { + DEBUG(10, ("Transfer to gencache.tdb failed: %s\n", + tdb_errorstr(cache))); + state->error = true; + return -1; + } + + if (tdb_delete(cache_notrans, key) == -1) { + DEBUG(10, ("tdb_delete from gencache_notrans.tdb failed: " + "%s\n", tdb_errorstr(cache_notrans))); + state->error = true; + return -1; + } + return 0; +} + /** * Get existing entry from the cache file. * @@ -387,6 +626,7 @@ struct gencache_iterate_state { void *priv); const char *pattern; void *priv; + bool in_persistent; }; static int gencache_iterate_fn(struct tdb_context *tdb, TDB_DATA key, @@ -402,6 +642,14 @@ static int gencache_iterate_fn(struct tdb_context *tdb, TDB_DATA key, time_t timeout; char *timeout_endp; + if (tdb_data_cmp(key, last_stabilize_key()) == 0) { + return 0; + } + + if (state->in_persistent && tdb_exists(cache_notrans, key)) { + return 0; + } + if (key.dptr[key.dsize-1] == '\0') { keystr = (char *)key.dptr; } else { @@ -462,5 +710,10 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time state.fn = fn; state.pattern = keystr_pattern; state.priv = data; + + state.in_persistent = false; + tdb_traverse(cache_notrans, gencache_iterate_fn, &state); + + state.in_persistent = true; tdb_traverse(cache, gencache_iterate_fn, &state); } diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 848baeff3d..961e930728 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -82,6 +82,8 @@ static void terminate(void) /* If there was an async dns child - kill it. */ kill_async_dns_child(); + gencache_stabilize(); + pidfile_unlink(); exit(0); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 6951fac171..a1dec0327c 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -868,6 +868,7 @@ static void exit_server_common(enum server_exit_reason how, if (am_parent) { pidfile_unlink(); } + gencache_stabilize(); } /* if we had any open SMB connections when we exited then we diff --git a/source3/utils/net.c b/source3/utils/net.c index 0e3946f5a5..9f29ac42fe 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -762,6 +762,8 @@ static struct functable net_func[] = { DEBUG(2,("return code = %d\n", rc)); + gencache_stabilize(); + libnetapi_free(c->netapi_ctx); poptFreeContext(pc); diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c index 74d8d29b4b..36cd12fb82 100644 --- a/source3/utils/net_cache.c +++ b/source3/utils/net_cache.c @@ -297,6 +297,21 @@ static int net_cache_flush(struct net_context *c, int argc, const char **argv) return 0; } +static int net_cache_stabilize(struct net_context *c, int argc, + const char **argv) +{ + if (c->display_usage) { + d_printf("Usage:\n" + "net cache flush\n" + " Delete all cache entries.\n"); + return 0; + } + + if (!gencache_stabilize()) { + return -1; + } + return 0; +} /** * Entry point to 'net cache' subfunctionality * @@ -362,6 +377,14 @@ int net_cache(struct net_context *c, int argc, const char **argv) "net cache flush\n" " Delete all cache entries" }, + { + "stabilize", + net_cache_stabilize, + NET_TRANSPORT_LOCAL, + "Move transient cache content to stable storage", + "net cache stabilize\n" + " Move transient cache content to stable storage" + }, {NULL, NULL, 0, NULL, NULL} }; diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index d617fe1f0b..34eaeb2d79 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -163,6 +163,8 @@ static void terminate(bool is_parent) trustdom_cache_shutdown(); + gencache_stabilize(); + #if 0 if (interactive) { TALLOC_CTX *mem_ctx = talloc_init("end_description"); -- cgit From 3d7dfc1197017c34bdb8dbc6e62460f19bd7d141 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 11:33:04 +0200 Subject: Consolidate string and data_blob routines in gencache --- source3/include/proto.h | 3 +- source3/lib/gencache.c | 194 +++++++++++++------------------------------ source3/libsmb/dsgetdcname.c | 15 ++-- 3 files changed, 65 insertions(+), 147 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index dd49e53338..df7815587c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -518,7 +518,8 @@ void pull_file_id_24(char *buf, struct file_id *id); bool gencache_set(const char *keystr, const char *value, time_t timeout); bool gencache_del(const char *keystr); bool gencache_get(const char *keystr, char **valstr, time_t *timeout); -bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired); +bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, + time_t *timeout); bool gencache_stabilize(void); bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout); void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr), diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 73f433c1c0..6496ad3ed6 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -26,7 +26,7 @@ #define DBGC_CLASS DBGC_TDB #define TIMEOUT_LEN 12 -#define CACHE_DATA_FMT "%12u/%s" +#define CACHE_DATA_FMT "%12u/" #define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us" #define BLOB_TYPE "DATA_BLOB" #define BLOB_TYPE_LEN 9 @@ -107,18 +107,19 @@ static TDB_DATA last_stabilize_key(void) * one, then add it. * * @param keystr string that represents a key of this entry - * @param value text representation value being cached + * @param blob DATA_BLOB value being cached * @param timeout time when the value is expired * * @retval true when entry is successfuly stored * @retval false on failure **/ -bool gencache_set(const char *keystr, const char *value, time_t timeout) +bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, + time_t timeout) { int ret; TDB_DATA databuf; - char* valstr = NULL; + char* val; time_t last_stabilize; if (tdb_data_cmp(string_term_tdb_data(keystr), @@ -127,24 +128,35 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) return false; } - if ((keystr == NULL) || (value == NULL)) { + if ((keystr == NULL) || (blob == NULL)) { return false; } if (!gencache_init()) return False; - if (asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value) == -1) { + val = talloc_asprintf(talloc_tos(), CACHE_DATA_FMT, (int)timeout); + if (val == NULL) { return False; } + val = talloc_realloc(NULL, val, char, talloc_array_length(val)-1); + if (val == NULL) { + return false; + } + val = (char *)talloc_append_blob(NULL, val, *blob); + if (val == NULL) { + return false; + } - databuf = string_term_tdb_data(valstr); - DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout =" - " %s (%d seconds %s)\n", keystr, value,ctime(&timeout), + DEBUG(10, ("Adding cache entry with key = %s and timeout =" + " %s (%d seconds %s)\n", keystr, ctime(&timeout), (int)(timeout - time(NULL)), timeout > time(NULL) ? "ahead" : "in the past")); - ret = tdb_store_bystring(cache_notrans, keystr, databuf, 0); - SAFE_FREE(valstr); + ret = tdb_store_bystring( + cache_notrans, keystr, + make_tdb_data((uint8_t *)val, talloc_array_length(val)), + 0); + TALLOC_FREE(val); if (ret != 0) { return false; @@ -238,8 +250,7 @@ static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr) * Get existing entry from the cache file. * * @param keystr string that represents a key of this entry - * @param valstr buffer that is allocated and filled with the entry value - * buffer's disposing must be done outside + * @param blob DATA_BLOB that is filled with entry's blob * @param timeout pointer to a time_t that is filled with entry's * timeout * @@ -247,7 +258,8 @@ static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr) * @retval False for failure **/ -bool gencache_get(const char *keystr, char **valstr, time_t *timeout) +bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, + time_t *timeout) { TDB_DATA databuf; time_t t; @@ -308,11 +320,13 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout) return False; } - if (valstr) { - *valstr = SMB_STRDUP(endptr+1); - if (*valstr == NULL) { + if (blob != NULL) { + *blob = data_blob( + endptr+1, + databuf.dsize - PTR_DIFF(endptr+1, databuf.dptr)); + if (blob->data == NULL) { SAFE_FREE(databuf.dptr); - DEBUG(0, ("strdup failed\n")); + DEBUG(0, ("memdup failed\n")); return False; } } @@ -461,79 +475,39 @@ static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val, * Get existing entry from the cache file. * * @param keystr string that represents a key of this entry - * @param blob DATA_BLOB that is filled with entry's blob - * @param expired pointer to a bool that indicates whether the entry is expired + * @param valstr buffer that is allocated and filled with the entry value + * buffer's disposing must be done outside + * @param timeout pointer to a time_t that is filled with entry's + * timeout * * @retval true when entry is successfuly fetched * @retval False for failure **/ -bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired) +bool gencache_get(const char *keystr, char **value, time_t *ptimeout) { - TDB_DATA databuf; - time_t t; - char *blob_type; - unsigned char *buf = NULL; + DATA_BLOB blob; bool ret = False; - fstring valstr; - int buflen = 0, len = 0, blob_len = 0; - unsigned char *blob_buf = NULL; - if (keystr == NULL) { + ret = gencache_get_data_blob(keystr, &blob, ptimeout); + if (!ret) { return false; } - - if (!gencache_init()) { - return False; - } - - databuf = tdb_fetch_bystring(cache, keystr); - if (!databuf.dptr) { - DEBUG(10,("Cache entry with key = %s couldn't be found\n", - keystr)); - return False; - } - - buf = (unsigned char *)databuf.dptr; - buflen = databuf.dsize; - - len += tdb_unpack(buf+len, buflen-len, "fB", - &valstr, - &blob_len, &blob_buf); - if (len == -1) { - goto out; - } - - t = strtol(valstr, &blob_type, 10); - - if (strcmp(blob_type+1, BLOB_TYPE) != 0) { - goto out; + if ((blob.data == NULL) || (blob.length == 0)) { + SAFE_FREE(blob.data); + return false; } - - DEBUG(10,("Returning %s cache entry: key = %s, " - "timeout = %s", t > time(NULL) ? "valid" : - "expired", keystr, ctime(&t))); - - if (t <= time(NULL)) { - /* We're expired */ - if (expired) { - *expired = True; - } + if (blob.data[blob.length-1] != '\0') { + /* Not NULL terminated, can't be a string */ + SAFE_FREE(blob.data); + return false; } - - if (blob) { - *blob = data_blob(blob_buf, blob_len); - if (!blob->data) { - goto out; - } + *value = SMB_STRDUP((char *)blob.data); + data_blob_free(&blob); + if (*value == NULL) { + return false; } - - ret = True; - out: - SAFE_FREE(blob_buf); - SAFE_FREE(databuf.dptr); - - return ret; + return true; } /** @@ -541,73 +515,17 @@ bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired) * one, then add it. * * @param keystr string that represents a key of this entry - * @param blob DATA_BLOB value being cached + * @param value text representation value being cached * @param timeout time when the value is expired * * @retval true when entry is successfuly stored * @retval false on failure **/ -bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout) +bool gencache_set(const char *keystr, const char *value, time_t timeout) { - bool ret = False; - int tdb_ret; - TDB_DATA databuf; - char *valstr = NULL; - unsigned char *buf = NULL; - int len = 0, buflen = 0; - - if ((keystr == NULL) || (blob == NULL)) { - return false; - } - - if (!gencache_init()) { - return False; - } - - if (asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE) == -1) { - return False; - } - - again: - len = 0; - - len += tdb_pack(buf+len, buflen-len, "fB", - valstr, - blob->length, blob->data); - - if (len == -1) { - goto out; - } - - if (buflen < len) { - SAFE_FREE(buf); - buf = SMB_MALLOC_ARRAY(unsigned char, len); - if (!buf) { - goto out; - } - buflen = len; - goto again; - } - - databuf = make_tdb_data(buf, len); - - DEBUG(10,("Adding cache entry with key = %s; " - "blob size = %d and timeout = %s" - "(%d seconds %s)\n", keystr, (int)databuf.dsize, - ctime(&timeout), (int)(timeout - time(NULL)), - timeout > time(NULL) ? "ahead" : "in the past")); - - tdb_ret = tdb_store_bystring(cache, keystr, databuf, 0); - if (tdb_ret == 0) { - ret = True; - } - - out: - SAFE_FREE(valstr); - SAFE_FREE(buf); - - return ret; + DATA_BLOB blob = data_blob_const(value, strlen(value)+1); + return gencache_set_data_blob(keystr, &blob, timeout); } /** diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 9552ad1f22..3e0f4977aa 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -339,8 +339,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct netr_DsRGetDCNameInfo **info_p, - bool *expired) + struct netr_DsRGetDCNameInfo **info_p) { char *key; DATA_BLOB blob; @@ -354,8 +353,8 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - if (!gencache_get_data_blob(key, &blob, expired)) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + if (!gencache_get_data_blob(key, &blob, NULL)) { + return NT_STATUS_NOT_FOUND; } info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); @@ -410,11 +409,11 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, struct netr_DsRGetDCNameInfo **info) { NTSTATUS status; - bool expired = false; status = dsgetdcname_cache_fetch(mem_ctx, domain_name, domain_guid, - flags, site_name, info, &expired); - if (!NT_STATUS_IS_OK(status)) { + flags, site_name, info); + if (!NT_STATUS_IS_OK(status) + && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { DEBUG(10,("dsgetdcname_cached: cache fetch failed with: %s\n", nt_errstr(status))); return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; @@ -424,7 +423,7 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, return status; } - if (expired) { + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { status = dsgetdcname_cache_refresh(mem_ctx, msg_ctx, domain_name, domain_guid, flags, -- cgit From 76705d10c626a66cc77f3ec294f4f98bef95aeb5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 18:31:28 +0200 Subject: Consolidate gencache also every 100 writes in a single process --- source3/lib/gencache.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 6496ad3ed6..ee1f4b70b3 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -121,6 +121,7 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, TDB_DATA databuf; char* val; time_t last_stabilize; + static int writecount; if (tdb_data_cmp(string_term_tdb_data(keystr), last_stabilize_key()) == 0) { @@ -162,6 +163,18 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, return false; } + /* + * Every 100 writes within a single process, stabilize the cache with + * a transaction. This is done to prevent a single transaction to + * become huge and chew lots of memory. + */ + writecount += 1; + if (writecount > lp_parm_int(-1, "gencache", "stabilize_count", 100)) { + gencache_stabilize(); + writecount = 0; + goto done; + } + /* * Every 5 minutes, call gencache_stabilize() to not let grow * gencache_notrans.tdb too large. @@ -180,6 +193,7 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, gencache_stabilize(); } +done: return ret == 0; } -- cgit From af3444e6117de7d24bc2e3b61436f2804bfa1e4e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2009 10:09:54 +0200 Subject: SMB2-CONNECT: unlink the test file at startup This is needed to get reproducable results... metze --- source4/torture/smb2/connect.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/torture/smb2/connect.c b/source4/torture/smb2/connect.c index bd1abce827..fd32b52111 100644 --- a/source4/torture/smb2/connect.c +++ b/source4/torture/smb2/connect.c @@ -200,6 +200,8 @@ bool torture_smb2_connect(struct torture_context *torture) return false; } + smb2_util_unlink(tree, "test9.dat"); + h1 = torture_smb2_createfile(tree, "test9.dat"); h2 = torture_smb2_createfile(tree, "test9.dat"); status = torture_smb2_write(torture, tree, h1); -- cgit From da737f2447c925726fb944fc08683ffaf6cf8a63 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 12:25:40 +0200 Subject: s4:libcli/smb2: add smb2_transport_credits_set_charge() to change the CreditsCharge value for the next request metze --- source4/libcli/smb2/request.c | 10 ++++++---- source4/libcli/smb2/smb2.h | 1 + source4/libcli/smb2/transport.c | 7 +++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index f3684ed280..5d09a5083a 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -78,9 +78,11 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ req = talloc(transport, struct smb2_request); if (req == NULL) return NULL; - seqnum = transport->seqnum++; - if (seqnum == UINT64_MAX) { - seqnum = transport->seqnum++; + seqnum = transport->seqnum; + if (transport->credits.charge > 0) { + transport->seqnum += transport->credits.charge; + } else { + transport->seqnum += 1; } req->state = SMB2_REQUEST_INIT; @@ -131,7 +133,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ SIVAL(req->out.hdr, 0, SMB2_MAGIC); SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); - SSVAL(req->out.hdr, SMB2_HDR_EPOCH, 0); + SSVAL(req->out.hdr, SMB2_HDR_EPOCH, transport->credits.charge); SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); SSVAL(req->out.hdr, SMB2_HDR_CREDIT, transport->credits.ask_num); diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index eb231984df..6372cd805b 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -87,6 +87,7 @@ struct smb2_transport { } compound; struct { + uint16_t charge; uint16_t ask_num; } credits; diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c index 60522370b7..dffd1acd2b 100644 --- a/source4/libcli/smb2/transport.c +++ b/source4/libcli/smb2/transport.c @@ -84,6 +84,7 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock, transport->socket = talloc_steal(transport, sock); transport->options = *options; + transport->credits.charge = 0; transport->credits.ask_num = 1; /* setup the stream -> packet parser */ @@ -552,6 +553,12 @@ void smb2_transport_credits_ask_num(struct smb2_transport *transport, transport->credits.ask_num = ask_num; } +void smb2_transport_credits_set_charge(struct smb2_transport *transport, + uint16_t charge) +{ + transport->credits.charge = charge; +} + static void idle_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { -- cgit From d3be108637f1ae5d2a07a87c700f42b8c26df6a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2009 13:32:23 +0200 Subject: SMB2-GETINFO: test SMB2_ALL_EAS metze --- source4/torture/smb2/getinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/torture/smb2/getinfo.c b/source4/torture/smb2/getinfo.c index c4ab31f4cf..166c3f694f 100644 --- a/source4/torture/smb2/getinfo.c +++ b/source4/torture/smb2/getinfo.c @@ -49,9 +49,9 @@ static struct { { LEVEL(RAW_FILEINFO_COMPRESSION_INFORMATION) }, { LEVEL(RAW_FILEINFO_NETWORK_OPEN_INFORMATION) }, { LEVEL(RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION) }, -/* + { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS) }, -*/ + { LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION) }, { LEVEL(RAW_FILEINFO_SEC_DESC) } }; -- cgit From b4abb190a97456e5176088d9ab555c93fd5ea731 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 11:54:07 +0200 Subject: s3:make test: smbtorture from s3 needs to take the config file path via the SMB_CONF_PATH envvar metze --- source3/script/tests/test_smbtorture_s3.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh index 2894d7e90a..602433bd91 100755 --- a/source3/script/tests/test_smbtorture_s3.sh +++ b/source3/script/tests/test_smbtorture_s3.sh @@ -21,6 +21,9 @@ incdir=`dirname $0` . $incdir/test_functions.sh } +SMB_CONF_PATH="$CONFFILE" +export SMB_CONF_PATH + tests="FDPASS LOCK1 LOCK2 LOCK3 LOCK4 LOCK5 LOCK6 LOCK7" #tests="$tests UNLINK BROWSE ATTR TRANS2 MAXFID TORTURE " tests="$tests UNLINK BROWSE ATTR TRANS2 TORTURE " -- cgit From fafe2589e684e1946431722c8845d0dadd9ab525 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2009 09:49:25 +0200 Subject: s3:lib: map ENOSYS to NT_STATUS_NOT_SUPPORTED instead of NT_STATUS_ACCESS_DENIED Jeremy: please check and decide if we want to backport this. metze --- source3/lib/errmap_unix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/lib/errmap_unix.c b/source3/lib/errmap_unix.c index 0c39a572ad..00c5475394 100644 --- a/source3/lib/errmap_unix.c +++ b/source3/lib/errmap_unix.c @@ -40,6 +40,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, { EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS }, { EINTR, ERRHRD, ERRgeneral, NT_STATUS_RETRY }, + { ENOSYS, ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED }, #ifdef ELOOP { ELOOP, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND }, #endif -- cgit From 9e2c50971ee309dfe2f36efa11f572e1d985d057 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2009 09:47:46 +0200 Subject: s3:smbd: check quota access against sec_initial_uid() instead of 0 And return an NTSTATUS mapped from errno. Instead of hardcoded values. metze --- source3/smbd/trans2.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index a862c1466f..d1f2e7ff18 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2952,17 +2952,17 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned fsp.fnum = -1; /* access check */ - if (conn->server_info->utok.uid != 0) { + if (conn->server_info->utok.uid != sec_initial_uid()) { DEBUG(0,("set_user_quota: access_denied " "service [%s] user [%s]\n", lp_servicename(SNUM(conn)), conn->server_info->unix_name)); - return NT_STATUS_DOS(ERRDOS, ERRnoaccess); + return NT_STATUS_ACCESS_DENIED; } if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); - return NT_STATUS_DOS(ERRSRV, ERRerror); + return map_nt_error_from_unix(errno); } data_len = 48; @@ -3446,12 +3446,12 @@ cap_low = 0x%x, cap_high = 0x%x\n", ZERO_STRUCT(quotas); /* access check */ - if ((conn->server_info->utok.uid != 0) + if ((conn->server_info->utok.uid != sec_initial_uid()) ||!CAN_WRITE(conn)) { DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", lp_servicename(SNUM(conn)), conn->server_info->unix_name)); - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return; } @@ -3520,7 +3520,7 @@ cap_low = 0x%x, cap_high = 0x%x\n", /* now set the quotas */ if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); - reply_doserror(req, ERRSRV, ERRerror); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } -- cgit From 9df1c8f2ad25a1875f2ca98df8c600aecf058144 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 09:23:36 +0200 Subject: s3:smbd: return NT_STATUS_INVALID_INFO_CLASS in SMB2 GetInfo metze --- source3/smbd/smb2_getinfo.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index b6b7462e90..cba6da45ce 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -297,7 +297,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, if (INFO_LEVEL_IS_UNIX(file_info_level)) { /* Always do lstat for UNIX calls. */ if (SMB_VFS_LSTAT(conn, smb_fname)) { - DEBUG(3,("call_trans2qfilepathinfo: " + DEBUG(3,("smbd_smb2_getinfo_send: " "SMB_VFS_LSTAT of %s failed " "(%s)\n", smb_fname_str_dbg(smb_fname), @@ -307,7 +307,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } } else if (SMB_VFS_STAT(conn, smb_fname)) { - DEBUG(3,("call_trans2qfilepathinfo: " + DEBUG(3,("smbd_smb2_getinfo_send: " "SMB_VFS_STAT of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); @@ -324,7 +324,8 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, */ if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { - DEBUG(3, ("fstat of fnum %d failed (%s)\n", + DEBUG(3, ("smbd_smb2_getinfo_send: " + "fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); @@ -350,6 +351,9 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, &data_size); if (!NT_STATUS_IS_OK(status)) { SAFE_FREE(data); + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { + status = NT_STATUS_INVALID_INFO_CLASS; + } tevent_req_nterror(req, status); return tevent_req_post(req, ev); } -- cgit From d85cc986b85d3c8a6e40491f216c801a1cbde2ab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 12:08:20 +0200 Subject: s3:smbd: implement SMB2 GetInfo with Fs*Information metze --- source3/smbd/smb2_getinfo.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index cba6da45ce..f8c2d41e31 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -370,6 +370,53 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, break; } + case 0x02:/* SMB2_GETINFO_FS */ + { + uint16_t file_info_level; + char *data = NULL; + int data_size = 0; + NTSTATUS status; + SMB_STRUCT_STAT st; + + /* the levels directly map to the passthru levels */ + file_info_level = in_file_info_class + 1000; + + if (vfs_stat_smb_fname(conn,".",&st)!=0) { + DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + status = smbd_do_qfsinfo(conn, state, + file_info_level, + st, + STR_UNICODE, + in_output_buffer_length, + &data, + &data_size); + if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(data); + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { + status = NT_STATUS_INVALID_INFO_CLASS; + } + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + if (data_size > 0) { + state->out_output_buffer = data_blob_talloc(state, + data, + data_size); + SAFE_FREE(data); + if (tevent_req_nomem(state->out_output_buffer.data, req)) { + return tevent_req_post(req, ev); + } + } + SAFE_FREE(data); + break; + } + default: tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return tevent_req_post(req, ev); -- cgit From 722cd5944f9b70c7f642ec1d510d54bf1592beb5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 09:23:57 +0200 Subject: s3:smbd: add support for SMB2 SetInfo File*Information metze --- source3/smbd/smb2_setinfo.c | 129 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c index 110ce6c64a..2974695c9f 100644 --- a/source3/smbd/smb2_setinfo.c +++ b/source3/smbd/smb2_setinfo.c @@ -200,7 +200,134 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + if (IS_IPC(conn)) { + tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); + return tevent_req_post(req, ev); + } + + switch (in_info_type) { + case 0x01:/* SMB2_SETINFO_FILE */ + { + uint16_t file_info_level; + struct smb_filename *smb_fname = NULL; + char *data; + int data_size; + int ret_size = 0; + NTSTATUS status; + + + file_info_level = in_file_info_class + 1000; + if (file_info_level == SMB_FILE_RENAME_INFORMATION) { + file_info_level = 0xFF00 + in_file_info_class; + } + + status = create_synthetic_smb_fname_split(state, + fsp->fsp_name, + NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + if (fsp->is_directory || fsp->fh->fd == -1) { + /* + * This is actually a SETFILEINFO on a directory + * handle (returned from an NT SMB). NT5.0 seems + * to do this call. JRA. + */ + if (INFO_LEVEL_IS_UNIX(file_info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname)) { + DEBUG(3,("smbd_smb2_setinfo_send: " + "SMB_VFS_LSTAT of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + } else { + if (SMB_VFS_STAT(conn, smb_fname) != 0) { + DEBUG(3,("smbd_smb2_setinfo_send: " + "fileinfo of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + } + } else if (fsp->print_file) { + /* + * Doing a DELETE_ON_CLOSE should cancel a print job. + */ + if ((file_info_level == SMB_SET_FILE_DISPOSITION_INFO) + && in_input_buffer.length >= 1 + && CVAL(in_input_buffer.data,0)) { + fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; + + DEBUG(3,("smbd_smb2_setinfo_send: " + "Cancelling print job (%s)\n", + fsp->fsp_name)); + + tevent_req_done(req); + return tevent_req_post(req, ev); + } else { + tevent_req_nterror(req, + NT_STATUS_OBJECT_PATH_INVALID); + return tevent_req_post(req, ev); + } + } else { + /* + * Original code - this is an open file. + */ + + if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + DEBUG(3,("smbd_smb2_setinfo_send: fstat " + "of fnum %d failed (%s)\n", fsp->fnum, + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + } + + data = NULL; + data_size = in_input_buffer.length; + if (data_size > 0) { + data = (char *)SMB_MALLOC_ARRAY(char, data_size); + if (tevent_req_nomem(data, req)) { + + } + memcpy(data, in_input_buffer.data, data_size); + } + + status = smbd_do_setfilepathinfo(conn, smbreq, state, + file_info_level, + fsp, + smb_fname, + &data, + data_size, + &ret_size); + SAFE_FREE(data); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { + status = NT_STATUS_INVALID_INFO_CLASS; + } + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + break; + } + + default: + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + tevent_req_done(req); return tevent_req_post(req, ev); } -- cgit From f49129e59225f6ea84add8e845ffaeb03dc6c8da Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 12:14:32 +0200 Subject: torture/smb2: add missing new line to the new SMB2-DIR.FILE-INDEX test Without this the subunit formated output would be invalid and make test reports: "UNEXPECTED(error): samba4.smb2.dir (dc).FILE-INDEX" metze --- source4/torture/smb2/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/torture/smb2/dir.c b/source4/torture/smb2/dir.c index e090c31ec9..4b44a50bbd 100644 --- a/source4/torture/smb2/dir.c +++ b/source4/torture/smb2/dir.c @@ -1182,7 +1182,7 @@ static bool test_file_index(struct torture_context *tctx, torture_comment(tctx, "Not an error. Resuming using a file " "index is an optional feature of the " - "protocol."); + "protocol.\n"); goto done; } } -- cgit From 5b594c695884aebdfbb199549901fea954122929 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 14:00:42 +0200 Subject: s3:dbwrap: add a wrapper dbwrap_trans_do() This function wraps the action() callback into a db transaction and the transaction is either committed or cancelled, depending on the return value of the action function. Michael --- source3/include/proto.h | 3 +++ source3/lib/dbwrap_util.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index df7815587c..74cedcec18 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -454,6 +454,9 @@ NTSTATUS dbwrap_trans_store_uint32(struct db_context *db, const char *keystr, NTSTATUS dbwrap_trans_store_bystring(struct db_context *db, const char *key, TDB_DATA data, int flags); NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key); +NTSTATUS dbwrap_trans_do(struct db_context *db, + NTSTATUS (*action)(struct db_context *, void *), + void *private_data); /* The following definitions come from lib/debug.c */ diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 3be3a49e7d..67471b5c96 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -307,3 +307,36 @@ NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key) { return dbwrap_trans_delete(db, string_term_tdb_data(key)); } + +/** + * Wrap db action(s) into a transaction. + */ +NTSTATUS dbwrap_trans_do(struct db_context *db, + NTSTATUS (*action)(struct db_context *, void *), + void *private_data) +{ + int res; + NTSTATUS status; + + res = db->transaction_start(db); + if (res != 0) { + DEBUG(5, ("transaction_start failed\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = action(db, private_data); + if (!NT_STATUS_IS_OK(status)) { + if (db->transaction_cancel(db) != 0) { + smb_panic("Cancelling transaction failed"); + } + return status; + } + + res = db->transaction_commit(db); + if (res == 0) { + return NT_STATUS_OK; + } + + DEBUG(2, ("transaction_commit failed\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; +} -- cgit From 804d3f897be01e9088deefe807cd06fe194c5d58 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 16:02:19 +0200 Subject: s3:dbwrap: add dbwrap_delete_bystring_upper() To delete a key whose name is not given in but stored in uppercase. Michael --- source3/include/proto.h | 1 + source3/lib/dbwrap_util.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 74cedcec18..4bc4cd197b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -457,6 +457,7 @@ NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key); NTSTATUS dbwrap_trans_do(struct db_context *db, NTSTATUS (*action)(struct db_context *, void *), void *private_data); +NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key); /* The following definitions come from lib/debug.c */ diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 67471b5c96..aca4b52697 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -340,3 +340,19 @@ NTSTATUS dbwrap_trans_do(struct db_context *db, DEBUG(2, ("transaction_commit failed\n")); return NT_STATUS_INTERNAL_DB_CORRUPTION; } + +NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key) +{ + char *key_upper; + NTSTATUS status; + + key_upper = talloc_strdup_upper(talloc_tos(), key); + if (key_upper == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = dbwrap_delete_bystring(db, key_upper); + + talloc_free(key_upper); + return status; +} -- cgit From 32a3275344819cfcbcb4540a1909617b8db6dc63 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 16:08:41 +0200 Subject: s3:dbwrap: add dbwrap_store_bystring_upper(). This stores a key under the uppercase version of the given keyname. Michael --- source3/include/proto.h | 2 ++ source3/lib/dbwrap_util.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 4bc4cd197b..81892f294d 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -458,6 +458,8 @@ NTSTATUS dbwrap_trans_do(struct db_context *db, NTSTATUS (*action)(struct db_context *, void *), void *private_data); NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key); +NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key, + TDB_DATA data, int flags); /* The following definitions come from lib/debug.c */ diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index aca4b52697..154bf6b553 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -356,3 +356,20 @@ NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key) talloc_free(key_upper); return status; } + +NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key, + TDB_DATA data, int flags) +{ + char *key_upper; + NTSTATUS status; + + key_upper = talloc_strdup_upper(talloc_tos(), key); + if (key_upper == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = dbwrap_store_bystring(db, key_upper, data, flags); + + talloc_free(key_upper); + return status; +} -- cgit From 3b3125fc23dc4b7a403d17af2ad2d5c592d3d090 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 16:13:07 +0200 Subject: s3:dbwrap: add dbwrap_fetch_bystring_upper(). To fetch a key whose name is stored but not given in upper case. Michael --- source3/include/proto.h | 2 ++ source3/lib/dbwrap_util.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 81892f294d..56bffd5ce7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -460,6 +460,8 @@ NTSTATUS dbwrap_trans_do(struct db_context *db, NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key); NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key, TDB_DATA data, int flags); +TDB_DATA dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx, + const char *key); /* The following definitions come from lib/debug.c */ diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 154bf6b553..01c18439c3 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -373,3 +373,20 @@ NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key, talloc_free(key_upper); return status; } + +TDB_DATA dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx, + const char *key) +{ + char *key_upper; + TDB_DATA result; + + key_upper = talloc_strdup_upper(talloc_tos(), key); + if (key_upper == NULL) { + return make_tdb_data(NULL, 0); + } + + result = dbwrap_fetch_bystring(db, mem_ctx, key_upper); + + talloc_free(key_upper); + return result; +} -- cgit From 3071b0712211b17b464f62d544fa16da5a128b01 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 09:58:02 +0200 Subject: s3:dbwrap_util: add my C Michael --- source3/lib/dbwrap_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 01c18439c3..6c95672986 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. Utility functions for the dbwrap API Copyright (C) Volker Lendecke 2007 + Copyrithg (C) Michael Adam 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 -- cgit From d554c0d7a923f1194463481f0bd829042cee574a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 16:16:18 +0200 Subject: s3:registry: don't store differently cased entries for the same keys. This happened for instance during registry initialization, when entries for HKLM\Software and HKLM\SOFTWARE were created. Searching these entries was case insensitive though. But the entries ended up in the subkey-lists anyways. This is solved by making the subkeys_hash in the regsubkey_container structs case insensitive (using the new _bystring_upper() wrappers). Michael --- source3/registry/reg_objects.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 5ae1cd8aa7..a592c76e1d 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -89,7 +89,7 @@ static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr, { WERROR werr; - werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash, + werr = ntstatus_to_werror(dbwrap_store_bystring_upper(ctr->subkeys_hash, keyname, make_tdb_data((uint8 *)&idx, sizeof(idx)), @@ -107,7 +107,7 @@ static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr, { WERROR werr; - werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash, + werr = ntstatus_to_werror(dbwrap_delete_bystring_upper(ctr->subkeys_hash, keyname)); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("error unhashing key '%s' in container: %s\n", @@ -127,7 +127,7 @@ static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr, return WERR_INVALID_PARAM; } - data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname); + data = dbwrap_fetch_bystring_upper(ctr->subkeys_hash, ctr, keyname); if (data.dptr == NULL) { return WERR_NOT_FOUND; } -- cgit From 2b380c73a4796bdf69264e5ca6721ad0d67087e9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 16:40:43 +0200 Subject: s3:registry: add db_context argument to regdb_delete_key_with_prefix() Michael --- source3/registry/reg_backend_db.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index e296d319e2..bdb237aafc 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -511,7 +511,8 @@ int regdb_get_seqnum(void) } -static WERROR regdb_delete_key_with_prefix(const char *keyname, +static WERROR regdb_delete_key_with_prefix(struct db_context *db, + const char *keyname, const char *prefix) { char *path; @@ -537,7 +538,7 @@ static WERROR regdb_delete_key_with_prefix(const char *keyname, goto done; } - werr = ntstatus_to_werror(dbwrap_delete_bystring(regdb, path)); + werr = ntstatus_to_werror(dbwrap_delete_bystring(db, path)); /* treat "not" found" as ok */ if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) { @@ -552,17 +553,17 @@ done: static WERROR regdb_delete_values(const char *keyname) { - return regdb_delete_key_with_prefix(keyname, REG_VALUE_PREFIX); + return regdb_delete_key_with_prefix(regdb, keyname, REG_VALUE_PREFIX); } static WERROR regdb_delete_secdesc(const char *keyname) { - return regdb_delete_key_with_prefix(keyname, REG_SECDESC_PREFIX); + return regdb_delete_key_with_prefix(regdb, keyname, REG_SECDESC_PREFIX); } static WERROR regdb_delete_subkeylist(const char *keyname) { - return regdb_delete_key_with_prefix(keyname, NULL); + return regdb_delete_key_with_prefix(regdb, keyname, NULL); } static WERROR regdb_delete_key_lists(const char *keyname) -- cgit From ec6b6727d824bea1b4a7b320e7a3c1de38df6724 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 16:42:20 +0200 Subject: s3:registry: add db_context argument to regdb_delete_values() Michael --- source3/registry/reg_backend_db.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index bdb237aafc..bcec77926b 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -551,9 +551,9 @@ done: } -static WERROR regdb_delete_values(const char *keyname) +static WERROR regdb_delete_values(struct db_context *db, const char *keyname) { - return regdb_delete_key_with_prefix(regdb, keyname, REG_VALUE_PREFIX); + return regdb_delete_key_with_prefix(db, keyname, REG_VALUE_PREFIX); } static WERROR regdb_delete_secdesc(const char *keyname) @@ -570,7 +570,7 @@ static WERROR regdb_delete_key_lists(const char *keyname) { WERROR werr; - werr = regdb_delete_values(keyname); + werr = regdb_delete_values(regdb, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", REG_VALUE_PREFIX, keyname, win_errstr(werr))); -- cgit From bd983dba6b308c28019c2e39f16de8b9e434e4f5 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 16:44:20 +0200 Subject: s3:registry: add db_context argument to regdb_delete_secdesc() Michael --- source3/registry/reg_backend_db.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index bcec77926b..1a6ae7bb45 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -556,9 +556,9 @@ static WERROR regdb_delete_values(struct db_context *db, const char *keyname) return regdb_delete_key_with_prefix(db, keyname, REG_VALUE_PREFIX); } -static WERROR regdb_delete_secdesc(const char *keyname) +static WERROR regdb_delete_secdesc(struct db_context *db, const char *keyname) { - return regdb_delete_key_with_prefix(regdb, keyname, REG_SECDESC_PREFIX); + return regdb_delete_key_with_prefix(db, keyname, REG_SECDESC_PREFIX); } static WERROR regdb_delete_subkeylist(const char *keyname) @@ -577,7 +577,7 @@ static WERROR regdb_delete_key_lists(const char *keyname) goto done; } - werr = regdb_delete_secdesc(keyname); + werr = regdb_delete_secdesc(regdb, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", REG_SECDESC_PREFIX, keyname, win_errstr(werr))); -- cgit From 86e927cb056b30be3b2eecc1375549de71419b1f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 16:48:36 +0200 Subject: s3:registry: add db_context argument to regdb_delete_subkeylist() Michael --- source3/registry/reg_backend_db.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 1a6ae7bb45..69676b19e6 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -561,9 +561,9 @@ static WERROR regdb_delete_secdesc(struct db_context *db, const char *keyname) return regdb_delete_key_with_prefix(db, keyname, REG_SECDESC_PREFIX); } -static WERROR regdb_delete_subkeylist(const char *keyname) +static WERROR regdb_delete_subkeylist(struct db_context *db, const char *keyname) { - return regdb_delete_key_with_prefix(regdb, keyname, NULL); + return regdb_delete_key_with_prefix(db, keyname, NULL); } static WERROR regdb_delete_key_lists(const char *keyname) @@ -584,7 +584,7 @@ static WERROR regdb_delete_key_lists(const char *keyname) goto done; } - werr = regdb_delete_subkeylist(keyname); + werr = regdb_delete_subkeylist(regdb, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s failed: %s\n", keyname, win_errstr(werr))); -- cgit From 528bf38875b9e5412da0a2810b17f05b2c376312 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 16:51:26 +0200 Subject: s3:registry: add db_context argument to regdb_delete_key_lists() Michael --- source3/registry/reg_backend_db.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 69676b19e6..700db0140f 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -566,25 +566,25 @@ static WERROR regdb_delete_subkeylist(struct db_context *db, const char *keyname return regdb_delete_key_with_prefix(db, keyname, NULL); } -static WERROR regdb_delete_key_lists(const char *keyname) +static WERROR regdb_delete_key_lists(struct db_context *db, const char *keyname) { WERROR werr; - werr = regdb_delete_values(regdb, keyname); + werr = regdb_delete_values(db, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", REG_VALUE_PREFIX, keyname, win_errstr(werr))); goto done; } - werr = regdb_delete_secdesc(regdb, keyname); + werr = regdb_delete_secdesc(db, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", REG_SECDESC_PREFIX, keyname, win_errstr(werr))); goto done; } - werr = regdb_delete_subkeylist(regdb, keyname); + werr = regdb_delete_subkeylist(db, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s failed: %s\n", keyname, win_errstr(werr))); @@ -810,7 +810,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - werr = regdb_delete_key_lists(path); + werr = regdb_delete_key_lists(regdb, path); W_ERROR_NOT_OK_GOTO(werr, cancel); TALLOC_FREE(path); @@ -984,7 +984,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) werr = regdb_transaction_start(); W_ERROR_NOT_OK_GOTO_DONE(werr); - werr = regdb_delete_key_lists(path); + werr = regdb_delete_key_lists(regdb, path); W_ERROR_NOT_OK_GOTO(werr, cancel); werr = regsubkey_ctr_init(mem_ctx, &subkeys); -- cgit From a18a10c07a3e32644c31f4742805795998227e44 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 17:00:44 +0200 Subject: s3:registry: add db_context argument to regdb_store_keys_internal() Michael --- source3/registry/reg_backend_db.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 700db0140f..f4a269ef46 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -601,7 +601,9 @@ done: fstrings ***********************************************************************/ -static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr) +static bool regdb_store_keys_internal(struct db_context *db, + const char *key, + struct regsubkey_ctr *ctr) { TDB_DATA dbuf; uint8 *buffer = NULL; @@ -675,7 +677,7 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr dbuf.dptr = buffer; dbuf.dsize = len; - status = dbwrap_store_bystring(regdb, keyname, dbuf, TDB_REPLACE); + status = dbwrap_store_bystring(db, keyname, dbuf, TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { ret = false; goto done; @@ -688,7 +690,7 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX, keyname); if (keyname != NULL) { - dbwrap_delete_bystring(regdb, keyname); + dbwrap_delete_bystring(db, keyname); } done: @@ -820,7 +822,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) /* (2) store the subkey list for the parent */ - if (!regdb_store_keys_internal(key, ctr) ) { + if (!regdb_store_keys_internal(regdb, key, ctr)) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " "for parent [%s]\n", key)); goto cancel; @@ -837,7 +839,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - if (!regdb_store_keys_internal(key, subkeys)) { + if (!regdb_store_keys_internal(regdb, key, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", key)); goto cancel; @@ -861,7 +863,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) if (regdb_fetch_keys( path, subkeys ) == -1) { /* create a record with 0 subkeys */ - if (!regdb_store_keys_internal(path, subkeys)) { + if (!regdb_store_keys_internal(regdb, path, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", path)); goto cancel; @@ -931,7 +933,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_addkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal(key, subkeys)) { + if (!regdb_store_keys_internal(regdb, key, subkeys)) { DEBUG(0, (__location__ " failed to store new subkey list for " "parent key %s\n", key)); werr = WERR_REG_IO_FAILURE; @@ -998,7 +1000,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_delkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal(key, subkeys)) { + if (!regdb_store_keys_internal(regdb, key, subkeys)) { DEBUG(0, (__location__ " failed to store new subkey_list for " "parent key %s\n", key)); werr = WERR_REG_IO_FAILURE; -- cgit From c01d955ac0b6ef686cf026cc90074cd52a1a30ae Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 17:10:09 +0200 Subject: s3:registry: add db_context argument to regdb_fetch_key_internal() Michael --- source3/registry/reg_backend_db.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index f4a269ef46..165c0abf59 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1027,7 +1027,8 @@ done: return werr; } -static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key) +static TDB_DATA regdb_fetch_key_internal(struct db_context *db, + TALLOC_CTX *mem_ctx, const char *key) { char *path = NULL; TDB_DATA data; @@ -1037,7 +1038,7 @@ static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key) return make_tdb_data(NULL, 0); } - data = dbwrap_fetch_bystring(regdb, mem_ctx, path); + data = dbwrap_fetch_bystring(db, mem_ctx, path); TALLOC_FREE(path); return data; @@ -1325,7 +1326,7 @@ static bool regdb_key_exists(const char *key) p = strrchr(path, '/'); if (p == NULL) { /* this is a base key */ - value = regdb_fetch_key_internal(mem_ctx, path); + value = regdb_fetch_key_internal(regdb, mem_ctx, path); ret = (value.dptr != NULL); } else { *p = '\0'; @@ -1366,7 +1367,7 @@ int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) goto done; } - value = regdb_fetch_key_internal(frame, key); + value = regdb_fetch_key_internal(regdb, frame, key); if (value.dptr == NULL) { DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n", @@ -1501,7 +1502,7 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) values->seqnum = regdb_get_seqnum(); - value = regdb_fetch_key_internal(ctx, keystr); + value = regdb_fetch_key_internal(regdb, ctx, keystr); if (!value.dptr) { /* all keys have zero values by default */ -- cgit From db4f797e3533b97df844a50a92e8a27a9248092b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 17:18:19 +0200 Subject: s3:registry: add db_context argument to scan_parent_subkeys() Michael --- source3/registry/reg_backend_db.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 165c0abf59..562e29742d 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1245,7 +1245,8 @@ static int parent_subkey_scanner(TDB_DATA key, TDB_DATA data, return 0; } -static bool scan_parent_subkeys(const char *parent, const char *name) +static bool scan_parent_subkeys(struct db_context *db, const char *parent, + const char *name) { char *path = NULL; char *key = NULL; @@ -1272,8 +1273,8 @@ static bool scan_parent_subkeys(const char *parent, const char *name) } state.scanned = false; - res = regdb->parse_record(regdb, string_term_tdb_data(key), - parent_subkey_scanner, &state); + res = db->parse_record(db, string_term_tdb_data(key), + parent_subkey_scanner, &state); if (state.scanned) { result = state.found; @@ -1281,8 +1282,8 @@ static bool scan_parent_subkeys(const char *parent, const char *name) if (!create_sorted_subkeys(path, key)) { goto fail; } - res = regdb->parse_record(regdb, string_term_tdb_data(key), - parent_subkey_scanner, &state); + res = db->parse_record(db, string_term_tdb_data(key), + parent_subkey_scanner, &state); if ((res == 0) && (state.scanned)) { result = state.found; } @@ -1330,7 +1331,7 @@ static bool regdb_key_exists(const char *key) ret = (value.dptr != NULL); } else { *p = '\0'; - ret = scan_parent_subkeys(path, p+1); + ret = scan_parent_subkeys(regdb, path, p+1); } done: -- cgit From 589bacfbdb7541be5d339fcaf08272520bf6a1ac Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 17:39:17 +0200 Subject: s3:registry: create regdb_fetch_keys_internal() with db_context argument and let exported regdb_fetch_keys() just call regdb_fetch_keys_internal() with regdb as an argument. Internally, in reg_backend_db.c, always use the _internal version. Michael --- source3/registry/reg_backend_db.c | 62 ++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 562e29742d..efbd678437 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -27,8 +27,10 @@ static struct db_context *regdb = NULL; static int regdb_refcount; -static bool regdb_key_exists(const char *key); +static bool regdb_key_exists(struct db_context *db, const char *key); static bool regdb_key_is_base_key(const char *key); +static int regdb_fetch_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr); /* List the deepest path into the registry. All part components will be created.*/ @@ -173,7 +175,7 @@ static WERROR init_registry_key_internal(const char *add_path) goto fail; } - regdb_fetch_keys(base, subkeys); + regdb_fetch_keys_internal(regdb, base, subkeys); if (*subkeyname) { werr = regsubkey_ctr_addkey(subkeys, subkeyname); if (!W_ERROR_IS_OK(werr)) { @@ -202,7 +204,7 @@ WERROR init_registry_key(const char *add_path) { WERROR werr; - if (regdb_key_exists(add_path)) { + if (regdb_key_exists(regdb, add_path)) { return WERR_OK; } @@ -248,7 +250,7 @@ WERROR init_registry_data(void) * If all do already exist, we can save the writes. */ for (i=0; builtin_registry_paths[i] != NULL; i++) { - if (!regdb_key_exists(builtin_registry_paths[i])) { + if (!regdb_key_exists(regdb, builtin_registry_paths[i])) { goto do_init; } } @@ -294,7 +296,7 @@ do_init: /* loop over all of the predefined paths and add each component */ for (i=0; builtin_registry_paths[i] != NULL; i++) { - if (regdb_key_exists(builtin_registry_paths[i])) { + if (regdb_key_exists(regdb, builtin_registry_paths[i])) { continue; } werr = init_registry_key_internal(builtin_registry_paths[i]); @@ -713,7 +715,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) TALLOC_CTX *ctx = talloc_stackframe(); WERROR werr; - if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { + if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { goto fail; } @@ -728,7 +730,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) return false; } - regdb_fetch_keys(key, old_subkeys); + regdb_fetch_keys_internal(regdb, key, old_subkeys); num_subkeys = regsubkey_ctr_numkeys(ctr); old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); @@ -770,7 +772,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - regdb_fetch_keys(key, old_subkeys); + regdb_fetch_keys_internal(regdb, key, old_subkeys); /* * Make the store operation as safe as possible without transactions: @@ -861,7 +863,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - if (regdb_fetch_keys( path, subkeys ) == -1) { + if (regdb_fetch_keys_internal(regdb, path, subkeys) == -1) { /* create a record with 0 subkeys */ if (!regdb_store_keys_internal(regdb, path, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " @@ -899,7 +901,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) struct regsubkey_ctr *subkeys; TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { + if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { werr = WERR_NOT_FOUND; goto done; } @@ -907,7 +909,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys(key, subkeys) < 0) { + if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { werr = WERR_REG_IO_FAILURE; goto done; } @@ -925,7 +927,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (regdb_fetch_keys(key, subkeys) < 0) { + if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { werr = WERR_REG_IO_FAILURE; goto cancel; } @@ -967,7 +969,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) char *path; TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { + if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { werr = WERR_NOT_FOUND; goto done; } @@ -978,7 +980,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) goto done; } - if (!regdb_key_exists(path)) { + if (!regdb_key_exists(regdb, path)) { werr = WERR_OK; goto done; } @@ -992,7 +994,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (regdb_fetch_keys(key, subkeys) < 0) { + if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { werr = WERR_REG_IO_FAILURE; goto cancel; } @@ -1128,7 +1130,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) goto fail; } - res = regdb_fetch_keys(key, ctr); + res = regdb_fetch_keys_internal(regdb, key, ctr); if (res == -1) { goto fail; } @@ -1303,7 +1305,7 @@ static bool scan_parent_subkeys(struct db_context *db, const char *parent, * The exeption of this are keys without a parent key, * i.e. the "base" keys (HKLM, HKCU, ...). */ -static bool regdb_key_exists(const char *key) +static bool regdb_key_exists(struct db_context *db, const char *key) { TALLOC_CTX *mem_ctx = talloc_stackframe(); TDB_DATA value; @@ -1327,11 +1329,11 @@ static bool regdb_key_exists(const char *key) p = strrchr(path, '/'); if (p == NULL) { /* this is a base key */ - value = regdb_fetch_key_internal(regdb, mem_ctx, path); + value = regdb_fetch_key_internal(db, mem_ctx, path); ret = (value.dptr != NULL); } else { *p = '\0'; - ret = scan_parent_subkeys(regdb, path, p+1); + ret = scan_parent_subkeys(db, path, p+1); } done: @@ -1345,7 +1347,8 @@ done: released by the caller. ***********************************************************************/ -int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) +static int regdb_fetch_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr) { WERROR werr; uint32 num_items; @@ -1359,16 +1362,16 @@ int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL")); - if (!regdb_key_exists(key)) { + if (!regdb_key_exists(db, key)) { goto done; } - werr = regsubkey_ctr_set_seqnum(ctr, regdb_get_seqnum()); + werr = regsubkey_ctr_set_seqnum(ctr, db->get_seqnum(db)); if (!W_ERROR_IS_OK(werr)) { goto done; } - value = regdb_fetch_key_internal(regdb, frame, key); + value = regdb_fetch_key_internal(db, frame, key); if (value.dptr == NULL) { DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n", @@ -1399,6 +1402,11 @@ done: return ret; } +int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) +{ + return regdb_fetch_keys_internal(regdb, key, ctr); +} + /**************************************************************************** Unpack a list of registry values frem the TDB ***************************************************************************/ @@ -1492,7 +1500,7 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key)); - if (!regdb_key_exists(key)) { + if (!regdb_key_exists(regdb, key)) { goto done; } @@ -1529,7 +1537,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values) DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key)); - if (!regdb_key_exists(key)) { + if (!regdb_key_exists(regdb, key)) { goto done; } @@ -1587,7 +1595,7 @@ static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key, DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key)); - if (!regdb_key_exists(key)) { + if (!regdb_key_exists(regdb, key)) { err = WERR_BADFILE; goto done; } @@ -1627,7 +1635,7 @@ static WERROR regdb_set_secdesc(const char *key, WERROR err = WERR_NOMEM; TDB_DATA tdbdata; - if (!regdb_key_exists(key)) { + if (!regdb_key_exists(regdb, key)) { err = WERR_BADFILE; goto done; } -- cgit From eb1958ca3d6cd30e292d2d013ff1ea63e65563fb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 11:11:10 +0200 Subject: s3:registry: rename regdb_store_keys_internal() to regdb_store_keys_internal2() Michael --- source3/registry/reg_backend_db.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index efbd678437..c29bd79525 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -603,9 +603,9 @@ done: fstrings ***********************************************************************/ -static bool regdb_store_keys_internal(struct db_context *db, - const char *key, - struct regsubkey_ctr *ctr) +static bool regdb_store_keys_internal2(struct db_context *db, + const char *key, + struct regsubkey_ctr *ctr) { TDB_DATA dbuf; uint8 *buffer = NULL; @@ -824,7 +824,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) /* (2) store the subkey list for the parent */ - if (!regdb_store_keys_internal(regdb, key, ctr)) { + if (!regdb_store_keys_internal2(regdb, key, ctr)) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " "for parent [%s]\n", key)); goto cancel; @@ -841,7 +841,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - if (!regdb_store_keys_internal(regdb, key, subkeys)) { + if (!regdb_store_keys_internal2(regdb, key, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", key)); goto cancel; @@ -865,7 +865,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) if (regdb_fetch_keys_internal(regdb, path, subkeys) == -1) { /* create a record with 0 subkeys */ - if (!regdb_store_keys_internal(regdb, path, subkeys)) { + if (!regdb_store_keys_internal2(regdb, path, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", path)); goto cancel; @@ -935,7 +935,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_addkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal(regdb, key, subkeys)) { + if (!regdb_store_keys_internal2(regdb, key, subkeys)) { DEBUG(0, (__location__ " failed to store new subkey list for " "parent key %s\n", key)); werr = WERR_REG_IO_FAILURE; @@ -1002,7 +1002,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_delkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal(regdb, key, subkeys)) { + if (!regdb_store_keys_internal2(regdb, key, subkeys)) { DEBUG(0, (__location__ " failed to store new subkey_list for " "parent key %s\n", key)); werr = WERR_REG_IO_FAILURE; @@ -1097,7 +1097,7 @@ done: * parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of * the potentially large subkey record. * - * The sorted subkey record is deleted in regdb_store_keys_internal and + * The sorted subkey record is deleted in regdb_store_keys_internal2 and * recreated on demand. */ -- cgit From 1dfaa371fa027351a0af6e56a04bc045c3b0dc73 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 11:31:28 +0200 Subject: s3:registry: create regdb_store_keys_internal() with db_context argument and let exported regdb_store_keys() just call regdb_store_keys_internal() with regdb as an argument. Internally, in reg_backend_db.c, always use the _internal version. Michael --- source3/registry/reg_backend_db.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index c29bd79525..78ac64d5c1 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -31,6 +31,8 @@ static bool regdb_key_exists(struct db_context *db, const char *key); static bool regdb_key_is_base_key(const char *key); static int regdb_fetch_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); +static bool regdb_store_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr); /* List the deepest path into the registry. All part components will be created.*/ @@ -182,7 +184,7 @@ static WERROR init_registry_key_internal(const char *add_path) goto fail; } } - if (!regdb_store_keys( base, subkeys)) { + if (!regdb_store_keys_internal(regdb, base, subkeys)) { werr = WERR_CAN_NOT_COMPLETE; goto fail; } @@ -706,7 +708,8 @@ done: do not currently exist ***********************************************************************/ -bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) +static bool regdb_store_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr) { int num_subkeys, old_num_subkeys, i; char *path = NULL; @@ -715,7 +718,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) TALLOC_CTX *ctx = talloc_stackframe(); WERROR werr; - if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { + if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) { goto fail; } @@ -730,7 +733,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) return false; } - regdb_fetch_keys_internal(regdb, key, old_subkeys); + regdb_fetch_keys_internal(db, key, old_subkeys); num_subkeys = regsubkey_ctr_numkeys(ctr); old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); @@ -757,7 +760,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) TALLOC_FREE(old_subkeys); - if (regdb->transaction_start(regdb) != 0) { + if (db->transaction_start(db) != 0) { DEBUG(0, ("regdb_store_keys: transaction_start failed\n")); goto fail; } @@ -772,7 +775,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - regdb_fetch_keys_internal(regdb, key, old_subkeys); + regdb_fetch_keys_internal(db, key, old_subkeys); /* * Make the store operation as safe as possible without transactions: @@ -814,7 +817,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - werr = regdb_delete_key_lists(regdb, path); + werr = regdb_delete_key_lists(db, path); W_ERROR_NOT_OK_GOTO(werr, cancel); TALLOC_FREE(path); @@ -824,7 +827,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) /* (2) store the subkey list for the parent */ - if (!regdb_store_keys_internal2(regdb, key, ctr)) { + if (!regdb_store_keys_internal2(db, key, ctr)) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " "for parent [%s]\n", key)); goto cancel; @@ -841,7 +844,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - if (!regdb_store_keys_internal2(regdb, key, subkeys)) { + if (!regdb_store_keys_internal2(db, key, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", key)); goto cancel; @@ -863,9 +866,9 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - if (regdb_fetch_keys_internal(regdb, path, subkeys) == -1) { + if (regdb_fetch_keys_internal(db, path, subkeys) == -1) { /* create a record with 0 subkeys */ - if (!regdb_store_keys_internal2(regdb, path, subkeys)) { + if (!regdb_store_keys_internal2(db, path, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", path)); goto cancel; @@ -876,7 +879,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) TALLOC_FREE(path); } - if (regdb->transaction_commit(regdb) != 0) { + if (db->transaction_commit(db) != 0) { DEBUG(0, ("regdb_store_keys: Could not commit transaction\n")); goto fail; } @@ -885,7 +888,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) return true; cancel: - if (regdb->transaction_cancel(regdb) != 0) { + if (db->transaction_cancel(db) != 0) { smb_panic("regdb_store_keys: transaction_cancel failed\n"); } @@ -895,6 +898,11 @@ fail: return false; } +bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) +{ + return regdb_store_keys_internal(regdb, key, ctr); +} + static WERROR regdb_create_subkey(const char *key, const char *subkey) { WERROR werr; -- cgit From 3409a44da2ee6a0ca2caaf0455e0095f8e2f80a4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 11:41:08 +0200 Subject: s3:registry: don't use exported transaction wrappers in regdb_create_subkey() So that the regdb handle is again explicit and the core of the function can be abstracted. Michael --- source3/registry/reg_backend_db.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 78ac64d5c1..6763558b0d 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -929,8 +929,10 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) talloc_free(subkeys); - werr = regdb_transaction_start(); - W_ERROR_NOT_OK_GOTO_DONE(werr); + if (regdb->transaction_start(regdb) != 0) { + werr = WERR_REG_IO_FAILURE; + goto done; + } werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO(werr, cancel); @@ -950,19 +952,17 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) goto cancel; } - werr = regdb_transaction_commit(); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " failed to commit transaction: %s\n", - win_errstr(werr))); + if (regdb->transaction_commit(regdb) != 0) { + werr = WERR_REG_IO_FAILURE; + DEBUG(0, (__location__ " failed to commit transaction\n")); } goto done; cancel: - werr = regdb_transaction_cancel(); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " failed to cancel transaction: %s\n", - win_errstr(werr))); + if (regdb->transaction_cancel(regdb) != 0) { + werr = WERR_REG_IO_FAILURE; + DEBUG(0, (__location__ " failed to cancel transaction\n")); } done: -- cgit From 355892c296f7f245e5a5dd9070e3e776bedbf09c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:20:23 +0200 Subject: s3:registry: panic upon failed transaction_cancel in regdb_create_subkey() Michael --- source3/registry/reg_backend_db.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 6763558b0d..880c84a1be 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -961,8 +961,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) cancel: if (regdb->transaction_cancel(regdb) != 0) { - werr = WERR_REG_IO_FAILURE; - DEBUG(0, (__location__ " failed to cancel transaction\n")); + smb_panic("regdb_create_subkey: transaction_cancel failed\n"); } done: -- cgit From 4eeacd6ef0e1bb813062c30ac280e542c6b007c8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:24:25 +0200 Subject: s3:registry: in regdb_delete_subkey(), panic if transaction_cancel fails Michael --- source3/registry/reg_backend_db.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 880c84a1be..0c916a8df6 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1027,8 +1027,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) cancel: werr2 = regdb_transaction_cancel(); if (!W_ERROR_IS_OK(werr2)) { - DEBUG(0, (__location__ " failed to cancel transaction: %s\n", - win_errstr(werr2))); + smb_panic("regdb_delete_subkey: transaction_cancel failed\n"); } done: -- cgit From 6cb14409af5f708706f975143c7b40bb54c7a5c0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:27:26 +0200 Subject: s3:registry: in regdb_delete_subkey(), don't use the transaction wrappers. This way, the db handle gets used explicitly and the core of the function can be abstracted. Michael --- source3/registry/reg_backend_db.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 0c916a8df6..979dc1867c 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -971,7 +971,7 @@ done: static WERROR regdb_delete_subkey(const char *key, const char *subkey) { - WERROR werr, werr2; + WERROR werr; struct regsubkey_ctr *subkeys; char *path; TALLOC_CTX *mem_ctx = talloc_stackframe(); @@ -992,8 +992,10 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) goto done; } - werr = regdb_transaction_start(); - W_ERROR_NOT_OK_GOTO_DONE(werr); + if (regdb->transaction_start(regdb) != 0) { + werr = WERR_REG_IO_FAILURE; + goto done; + } werr = regdb_delete_key_lists(regdb, path); W_ERROR_NOT_OK_GOTO(werr, cancel); @@ -1016,17 +1018,15 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) goto cancel; } - werr = regdb_transaction_commit(); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " failed to commit transaction: %s\n", - win_errstr(werr))); + if (regdb->transaction_commit(regdb) != 0) { + DEBUG(0, (__location__ " failed to commit transaction\n")); + werr = WERR_REG_IO_FAILURE; } goto done; cancel: - werr2 = regdb_transaction_cancel(); - if (!W_ERROR_IS_OK(werr2)) { + if (regdb->transaction_cancel(regdb) != 0) { smb_panic("regdb_delete_subkey: transaction_cancel failed\n"); } -- cgit From 4c366a094693f050b2cadea771cd5c6eab29e278 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:39:32 +0200 Subject: s3:registry: don't loop transaction_commit in create_sorted_subkeys() upon error This would try to commit a higher level transaction upon commit-error. Michael --- source3/registry/reg_backend_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 979dc1867c..dd9ca8b65c 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1203,7 +1203,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) if (regdb->transaction_commit(regdb) == -1) { DEBUG(0, ("create_sorted_subkeys: transaction_start " "failed\n")); - goto fail; + result = false; } TALLOC_FREE(ctr); -- cgit From 3189828087387686f63b3ae0b289c6e31f602a54 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:41:09 +0200 Subject: s3:registry: fix a comment in create_sorted_subkeys() Michael --- source3/registry/reg_backend_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index dd9ca8b65c..245e14b6d4 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1201,7 +1201,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) * a transaction_commit for transactions that we might be wrapped in. */ if (regdb->transaction_commit(regdb) == -1) { - DEBUG(0, ("create_sorted_subkeys: transaction_start " + DEBUG(0, ("create_sorted_subkeys: transaction_commit " "failed\n")); result = false; } -- cgit From a00109e1e6c1063b560be85c43ef820d3446ae31 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:42:09 +0200 Subject: s3:registry: panic upon error at transaction_cancel in create_sorted_subkeys Michael --- source3/registry/reg_backend_db.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 245e14b6d4..8806a93735 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1184,8 +1184,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) * transaction. See below for an explanation. */ if (regdb->transaction_cancel(regdb) == -1) { - DEBUG(0, ("create_sorted_subkeys: transaction_cancel " - "failed\n")); + smb_panic("create_sorted_subkeys: transaction_cancel " + "failed\n"); } TALLOC_FREE(ctr); return false; -- cgit From 95ebf534d2bc9904cc7c02bccdf5c01cc595ad7c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 23:03:46 +0200 Subject: s3:registry: add db_context argument to init_registry_key_internal() Michael --- source3/registry/reg_backend_db.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 8806a93735..d19eac3ccd 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -98,7 +98,8 @@ static struct builtin_regkey_value builtin_registry_values[] = { * Initialize a key in the registry: * create each component key of the specified path. */ -static WERROR init_registry_key_internal(const char *add_path) +static WERROR init_registry_key_internal(struct db_context *db, + const char *add_path) { WERROR werr; TALLOC_CTX *frame = talloc_stackframe(); @@ -177,14 +178,14 @@ static WERROR init_registry_key_internal(const char *add_path) goto fail; } - regdb_fetch_keys_internal(regdb, base, subkeys); + regdb_fetch_keys_internal(db, base, subkeys); if (*subkeyname) { werr = regsubkey_ctr_addkey(subkeys, subkeyname); if (!W_ERROR_IS_OK(werr)) { goto fail; } } - if (!regdb_store_keys_internal(regdb, base, subkeys)) { + if (!regdb_store_keys_internal(db, base, subkeys)) { werr = WERR_CAN_NOT_COMPLETE; goto fail; } @@ -215,7 +216,7 @@ WERROR init_registry_key(const char *add_path) return WERR_REG_IO_FAILURE; } - werr = init_registry_key_internal(add_path); + werr = init_registry_key_internal(regdb, add_path); if (!W_ERROR_IS_OK(werr)) { goto fail; } @@ -301,7 +302,8 @@ do_init: if (regdb_key_exists(regdb, builtin_registry_paths[i])) { continue; } - werr = init_registry_key_internal(builtin_registry_paths[i]); + werr = init_registry_key_internal(regdb, + builtin_registry_paths[i]); if (!W_ERROR_IS_OK(werr)) { goto fail; } -- cgit From 8a5b164b20c3d51df2422c1402ef31384b31472e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 23:58:03 +0200 Subject: s3:registry: use transaction wrapper in init_registry_key(). Michael --- source3/registry/reg_backend_db.c | 42 ++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index d19eac3ccd..74671a0790 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -198,6 +198,20 @@ fail: return werr; } +struct init_registry_key_context { + const char *add_path; +}; + +static NTSTATUS init_registry_key_action(struct db_context *db, + void *private_data) +{ + struct init_registry_key_context *init_ctx = + (struct init_registry_key_context *)private_data; + + return werror_to_ntstatus(init_registry_key_internal( + db, init_ctx->add_path)); +} + /** * Initialize a key in the registry: * create each component key of the specified path, @@ -205,35 +219,17 @@ fail: */ WERROR init_registry_key(const char *add_path) { - WERROR werr; + struct init_registry_key_context init_ctx; if (regdb_key_exists(regdb, add_path)) { return WERR_OK; } - if (regdb->transaction_start(regdb) != 0) { - DEBUG(0, ("init_registry_key: transaction_start failed\n")); - return WERR_REG_IO_FAILURE; - } + init_ctx.add_path = add_path; - werr = init_registry_key_internal(regdb, add_path); - if (!W_ERROR_IS_OK(werr)) { - goto fail; - } - - if (regdb->transaction_commit(regdb) != 0) { - DEBUG(0, ("init_registry_key: Could not commit transaction\n")); - return WERR_REG_IO_FAILURE; - } - - return WERR_OK; - -fail: - if (regdb->transaction_cancel(regdb) != 0) { - smb_panic("init_registry_key: transaction_cancel failed\n"); - } - - return werr; + return ntstatus_to_werror(dbwrap_trans_do(regdb, + init_registry_key_action, + &init_ctx)); } /*********************************************************************** -- cgit From 302265aae1bc27244ffaa9d803a8be83947e0381 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 12:32:48 +0200 Subject: s3:registry: add a regdb_fetch_values_internal() that takes a db_context argument Michael --- source3/registry/reg_backend_db.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 74671a0790..a5e882e9dc 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -33,6 +33,8 @@ static int regdb_fetch_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); static bool regdb_store_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); +static int regdb_fetch_values_internal(struct db_context *db, const char* key, + struct regval_ctr *values); /* List the deepest path into the registry. All part components will be created.*/ @@ -261,7 +263,9 @@ WERROR init_registry_data(void) goto done; } - regdb_fetch_values(builtin_registry_values[i].path, values); + regdb_fetch_values_internal(regdb, + builtin_registry_values[i].path, + values); if (!regval_ctr_key_exists(values, builtin_registry_values[i].valuename)) { @@ -315,7 +319,9 @@ do_init: goto fail; } - regdb_fetch_values(builtin_registry_values[i].path, values); + regdb_fetch_values_internal(regdb, + builtin_registry_values[i].path, + values); /* preserve existing values across restarts. Only add new ones */ @@ -1495,7 +1501,8 @@ static int regdb_pack_values(struct regval_ctr *values, uint8 *buf, int buflen) released by the caller. ***********************************************************************/ -int regdb_fetch_values(const char* key, struct regval_ctr *values) +static int regdb_fetch_values_internal(struct db_context *db, const char* key, + struct regval_ctr *values) { char *keystr = NULL; TALLOC_CTX *ctx = talloc_stackframe(); @@ -1504,7 +1511,7 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key)); - if (!regdb_key_exists(regdb, key)) { + if (!regdb_key_exists(db, key)) { goto done; } @@ -1513,9 +1520,9 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) goto done; } - values->seqnum = regdb_get_seqnum(); + values->seqnum = db->get_seqnum(db); - value = regdb_fetch_key_internal(regdb, ctx, keystr); + value = regdb_fetch_key_internal(db, ctx, keystr); if (!value.dptr) { /* all keys have zero values by default */ @@ -1530,6 +1537,11 @@ done: return ret; } +int regdb_fetch_values(const char* key, struct regval_ctr *values) +{ + return regdb_fetch_values_internal(regdb, key, values); +} + bool regdb_store_values(const char *key, struct regval_ctr *values) { TDB_DATA old_data, data; -- cgit From e6340963cf549cda261fc1ba9da4bc1b3a071241 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 12:38:41 +0200 Subject: s3:registry: add regdb_store_values_internal() that takes a db_context argument Michael --- source3/registry/reg_backend_db.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index a5e882e9dc..d2adc1ce08 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -35,6 +35,8 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); static int regdb_fetch_values_internal(struct db_context *db, const char* key, struct regval_ctr *values); +static bool regdb_store_values_internal(struct db_context *db, const char *key, + struct regval_ctr *values); /* List the deepest path into the registry. All part components will be created.*/ @@ -354,8 +356,9 @@ do_init: "[%d]\n", builtin_registry_values[i].type)); } - regdb_store_values(builtin_registry_values[i].path, - values); + regdb_store_values_internal(regdb, + builtin_registry_values[i].path, + values); } TALLOC_FREE(values); } @@ -1542,7 +1545,8 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) return regdb_fetch_values_internal(regdb, key, values); } -bool regdb_store_values(const char *key, struct regval_ctr *values) +static bool regdb_store_values_internal(struct db_context *db, const char *key, + struct regval_ctr *values) { TDB_DATA old_data, data; char *keystr = NULL; @@ -1553,7 +1557,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values) DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key)); - if (!regdb_key_exists(regdb, key)) { + if (!regdb_key_exists(db, key)) { goto done; } @@ -1581,7 +1585,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values) goto done; } - old_data = dbwrap_fetch_bystring(regdb, ctx, keystr); + old_data = dbwrap_fetch_bystring(db, ctx, keystr); if ((old_data.dptr != NULL) && (old_data.dsize == data.dsize) @@ -1591,7 +1595,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values) goto done; } - status = dbwrap_trans_store_bystring(regdb, keystr, data, TDB_REPLACE); + status = dbwrap_trans_store_bystring(db, keystr, data, TDB_REPLACE); result = NT_STATUS_IS_OK(status); @@ -1600,6 +1604,11 @@ done: return result; } +bool regdb_store_values(const char *key, struct regval_ctr *values) +{ + return regdb_store_values_internal(regdb, key, values); +} + static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key, struct security_descriptor **psecdesc) { -- cgit From cf4f808b8b03c385b5b9e9f4a5e891ae92143001 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 13:10:37 +0200 Subject: s3:registry: use transaction wrapper in init_registry_data() Michael --- source3/registry/reg_backend_db.c | 141 +++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 72 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index d2adc1ce08..bed9535f17 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -240,74 +240,25 @@ WERROR init_registry_key(const char *add_path) Open the registry data in the tdb ***********************************************************************/ -WERROR init_registry_data(void) +static NTSTATUS init_registry_data_action(struct db_context *db, + void *private_data) { - WERROR werr; + NTSTATUS status; TALLOC_CTX *frame = talloc_stackframe(); struct regval_ctr *values; int i; UNISTR2 data; - /* - * First, check for the existence of the needed keys and values. - * If all do already exist, we can save the writes. - */ - for (i=0; builtin_registry_paths[i] != NULL; i++) { - if (!regdb_key_exists(regdb, builtin_registry_paths[i])) { - goto do_init; - } - } - - for (i=0; builtin_registry_values[i].path != NULL; i++) { - values = TALLOC_ZERO_P(frame, struct regval_ctr); - if (values == NULL) { - werr = WERR_NOMEM; - goto done; - } - - regdb_fetch_values_internal(regdb, - builtin_registry_values[i].path, - values); - if (!regval_ctr_key_exists(values, - builtin_registry_values[i].valuename)) - { - TALLOC_FREE(values); - goto do_init; - } - - TALLOC_FREE(values); - } - - werr = WERR_OK; - goto done; - -do_init: - - /* - * There are potentially quite a few store operations which are all - * indiviually wrapped in tdb transactions. Wrapping them in a single - * transaction gives just a single transaction_commit() to actually do - * its fsync()s. See tdb/common/transaction.c for info about nested - * transaction behaviour. - */ - - if (regdb->transaction_start(regdb) != 0) { - DEBUG(0, ("init_registry_data: tdb_transaction_start " - "failed\n")); - werr = WERR_REG_IO_FAILURE; - goto done; - } - /* loop over all of the predefined paths and add each component */ for (i=0; builtin_registry_paths[i] != NULL; i++) { - if (regdb_key_exists(regdb, builtin_registry_paths[i])) { + if (regdb_key_exists(db, builtin_registry_paths[i])) { continue; } - werr = init_registry_key_internal(regdb, - builtin_registry_paths[i]); - if (!W_ERROR_IS_OK(werr)) { - goto fail; + status = werror_to_ntstatus(init_registry_key_internal(db, + builtin_registry_paths[i])); + if (!NT_STATUS_IS_OK(status)) { + goto done; } } @@ -317,11 +268,11 @@ do_init: values = TALLOC_ZERO_P(frame, struct regval_ctr); if (values == NULL) { - werr = WERR_NOMEM; - goto fail; + status = NT_STATUS_NO_MEMORY; + goto done; } - regdb_fetch_values_internal(regdb, + regdb_fetch_values_internal(db, builtin_registry_values[i].path, values); @@ -356,29 +307,75 @@ do_init: "[%d]\n", builtin_registry_values[i].type)); } - regdb_store_values_internal(regdb, + regdb_store_values_internal(db, builtin_registry_values[i].path, values); } TALLOC_FREE(values); } - if (regdb->transaction_commit(regdb) != 0) { - DEBUG(0, ("init_registry_data: Could not commit " - "transaction\n")); - werr = WERR_REG_IO_FAILURE; - } else { - werr = WERR_OK; + status = NT_STATUS_OK; + +done: + + TALLOC_FREE(frame); + return status; +} + +WERROR init_registry_data(void) +{ + WERROR werr; + TALLOC_CTX *frame = talloc_stackframe(); + struct regval_ctr *values; + int i; + + /* + * First, check for the existence of the needed keys and values. + * If all do already exist, we can save the writes. + */ + for (i=0; builtin_registry_paths[i] != NULL; i++) { + if (!regdb_key_exists(regdb, builtin_registry_paths[i])) { + goto do_init; + } } - goto done; + for (i=0; builtin_registry_values[i].path != NULL; i++) { + values = TALLOC_ZERO_P(frame, struct regval_ctr); + if (values == NULL) { + werr = WERR_NOMEM; + goto done; + } -fail: - if (regdb->transaction_cancel(regdb) != 0) { - smb_panic("init_registry_data: tdb_transaction_cancel " - "failed\n"); + regdb_fetch_values_internal(regdb, + builtin_registry_values[i].path, + values); + if (!regval_ctr_key_exists(values, + builtin_registry_values[i].valuename)) + { + TALLOC_FREE(values); + goto do_init; + } + + TALLOC_FREE(values); } + werr = WERR_OK; + goto done; + +do_init: + + /* + * There are potentially quite a few store operations which are all + * indiviually wrapped in tdb transactions. Wrapping them in a single + * transaction gives just a single transaction_commit() to actually do + * its fsync()s. See tdb/common/transaction.c for info about nested + * transaction behaviour. + */ + + werr = ntstatus_to_werror(dbwrap_trans_do(regdb, + init_registry_data_action, + NULL)); + done: TALLOC_FREE(frame); return werr; -- cgit From 1c65c98f3350951fe9f87a942b4c8a8094c8b781 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 13:58:52 +0200 Subject: s3:registry: refactor adding of builtin reg values out into regdb_ctr_add_value(). For readability. Michael --- source3/registry/reg_backend_db.c | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index bed9535f17..d04d34bac0 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -240,6 +240,31 @@ WERROR init_registry_key(const char *add_path) Open the registry data in the tdb ***********************************************************************/ +static void regdb_ctr_add_value(struct regval_ctr *ctr, + struct builtin_regkey_value *value) +{ + UNISTR2 data; + + switch(value->type) { + case REG_DWORD: + regval_ctr_addvalue(ctr, value->valuename, REG_DWORD, + (char*)&value->data.dw_value, + sizeof(uint32)); + break; + + case REG_SZ: + init_unistr2(&data, value->data.string, UNI_STR_TERMINATE); + regval_ctr_addvalue(ctr, value->valuename, REG_SZ, + (char*)data.buffer, + data.uni_str_len*sizeof(uint16)); + break; + + default: + DEBUG(0, ("regdb_ctr_add_value: invalid value type in " + "registry values [%d]\n", value->type)); + } +} + static NTSTATUS init_registry_data_action(struct db_context *db, void *private_data) { @@ -247,7 +272,6 @@ static NTSTATUS init_registry_data_action(struct db_context *db, TALLOC_CTX *frame = talloc_stackframe(); struct regval_ctr *values; int i; - UNISTR2 data; /* loop over all of the predefined paths and add each component */ @@ -281,32 +305,8 @@ static NTSTATUS init_registry_data_action(struct db_context *db, if (!regval_ctr_key_exists(values, builtin_registry_values[i].valuename)) { - switch(builtin_registry_values[i].type) { - case REG_DWORD: - regval_ctr_addvalue(values, - builtin_registry_values[i].valuename, - REG_DWORD, - (char*)&builtin_registry_values[i].data.dw_value, - sizeof(uint32)); - break; - - case REG_SZ: - init_unistr2(&data, - builtin_registry_values[i].data.string, - UNI_STR_TERMINATE); - regval_ctr_addvalue(values, - builtin_registry_values[i].valuename, - REG_SZ, - (char*)data.buffer, - data.uni_str_len*sizeof(uint16)); - break; - - default: - DEBUG(0, ("init_registry_data: invalid value " - "type in builtin_registry_values " - "[%d]\n", - builtin_registry_values[i].type)); - } + regdb_ctr_add_value(values, + &builtin_registry_values[i]); regdb_store_values_internal(db, builtin_registry_values[i].path, values); -- cgit From 14f593aa0f43127ab78aec848b0fe5933c0c28c9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 17:26:06 +0200 Subject: s3:registry: change regdb_store_keys_internal2() to return WERROR instead of bool for better error propagation. Michael --- source3/registry/reg_backend_db.c | 71 ++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index d04d34bac0..419bfd00f5 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -609,27 +609,26 @@ done: fstrings ***********************************************************************/ -static bool regdb_store_keys_internal2(struct db_context *db, - const char *key, - struct regsubkey_ctr *ctr) +static WERROR regdb_store_keys_internal2(struct db_context *db, + const char *key, + struct regsubkey_ctr *ctr) { TDB_DATA dbuf; uint8 *buffer = NULL; int i = 0; uint32 len, buflen; - bool ret = true; uint32 num_subkeys = regsubkey_ctr_numkeys(ctr); char *keyname = NULL; TALLOC_CTX *ctx = talloc_stackframe(); - NTSTATUS status; + WERROR werr; if (!key) { - return false; + return WERR_INVALID_PARAM; } keyname = talloc_strdup(ctx, key); if (!keyname) { - return false; + return WERR_NOMEM; } keyname = normalize_reg_path(ctx, keyname); @@ -637,7 +636,8 @@ static bool regdb_store_keys_internal2(struct db_context *db, buffer = (uint8 *)SMB_MALLOC(1024); if (buffer == NULL) { - return false; + werr = WERR_NOMEM; + goto done; } buflen = 1024; len = 0; @@ -665,7 +665,7 @@ static bool regdb_store_keys_internal2(struct db_context *db, DEBUG(0, ("regdb_store_keys: Failed to realloc " "memory of size [%u]\n", (unsigned int)(len+thistime)*2)); - ret = false; + werr = WERR_NOMEM; goto done; } buflen = (len+thistime)*2; @@ -674,7 +674,7 @@ static bool regdb_store_keys_internal2(struct db_context *db, regsubkey_ctr_specific_key(ctr, i)); if (thistime2 != thistime) { DEBUG(0, ("tdb_pack failed\n")); - ret = false; + werr = WERR_CAN_NOT_COMPLETE; goto done; } } @@ -685,11 +685,9 @@ static bool regdb_store_keys_internal2(struct db_context *db, dbuf.dptr = buffer; dbuf.dsize = len; - status = dbwrap_store_bystring(db, keyname, dbuf, TDB_REPLACE); - if (!NT_STATUS_IS_OK(status)) { - ret = false; - goto done; - } + werr = ntstatus_to_werror(dbwrap_store_bystring(db, keyname, dbuf, + TDB_REPLACE)); + W_ERROR_NOT_OK_GOTO_DONE(werr); /* * Delete a sorted subkey cache for regdb_key_exists, will be @@ -697,14 +695,22 @@ static bool regdb_store_keys_internal2(struct db_context *db, */ keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX, keyname); - if (keyname != NULL) { - dbwrap_delete_bystring(db, keyname); + if (keyname == NULL) { + werr = WERR_NOMEM; + goto done; + } + + werr = ntstatus_to_werror(dbwrap_delete_bystring(db, keyname)); + + /* don't treat WERR_NOT_FOUND as an error here */ + if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) { + werr = WERR_OK; } done: TALLOC_FREE(ctx); SAFE_FREE(buffer); - return ret; + return werr; } /*********************************************************************** @@ -831,9 +837,10 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, /* (2) store the subkey list for the parent */ - if (!regdb_store_keys_internal2(db, key, ctr)) { + werr = regdb_store_keys_internal2(db, key, ctr); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " - "for parent [%s]\n", key)); + "for parent [%s]: %s\n", key, win_errstr(werr))); goto cancel; } @@ -848,9 +855,11 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, goto cancel; } - if (!regdb_store_keys_internal2(db, key, subkeys)) { + werr = regdb_store_keys_internal2(db, key, subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: Failed to store " - "new record for key [%s]\n", key)); + "new record for key [%s]: %s\n", key, + win_errstr(werr))); goto cancel; } TALLOC_FREE(subkeys); @@ -872,9 +881,11 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, if (regdb_fetch_keys_internal(db, path, subkeys) == -1) { /* create a record with 0 subkeys */ - if (!regdb_store_keys_internal2(db, path, subkeys)) { + werr = regdb_store_keys_internal2(db, path, subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: Failed to store " - "new record for key [%s]\n", path)); + "new record for key [%s]: %s\n", path, + win_errstr(werr))); goto cancel; } } @@ -949,10 +960,10 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_addkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal2(regdb, key, subkeys)) { + werr = regdb_store_keys_internal2(regdb, key, subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0, (__location__ " failed to store new subkey list for " - "parent key %s\n", key)); - werr = WERR_REG_IO_FAILURE; + "parent key %s: %s\n", key, win_errstr(werr))); goto cancel; } @@ -1015,10 +1026,10 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_delkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal2(regdb, key, subkeys)) { + werr = regdb_store_keys_internal2(regdb, key, subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0, (__location__ " failed to store new subkey_list for " - "parent key %s\n", key)); - werr = WERR_REG_IO_FAILURE; + "parent key %s: %s\n", key, win_errstr(werr))); goto cancel; } -- cgit From 3eec829e2fa2106c8d52f31e3f3d7f45e6c81b24 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 00:10:08 +0200 Subject: s3:registry: unify exit logic and remove leaking to talloc_stack in regdb_store_keys_internal() Michael --- source3/registry/reg_backend_db.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 419bfd00f5..542f6dc7d0 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -727,9 +727,10 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, char *oldkeyname = NULL; TALLOC_CTX *ctx = talloc_stackframe(); WERROR werr; + bool ret = false; if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) { - goto fail; + goto done; } /* @@ -740,7 +741,7 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, werr = regsubkey_ctr_init(ctx, &old_subkeys); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - return false; + goto done; } regdb_fetch_keys_internal(db, key, old_subkeys); @@ -763,8 +764,9 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, * Nothing changed, no point to even start a tdb * transaction */ - TALLOC_FREE(old_subkeys); - return true; + + ret = true; + goto done; } } @@ -772,7 +774,7 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, if (db->transaction_start(db) != 0) { DEBUG(0, ("regdb_store_keys: transaction_start failed\n")); - goto fail; + goto done; } /* @@ -896,21 +898,22 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, if (db->transaction_commit(db) != 0) { DEBUG(0, ("regdb_store_keys: Could not commit transaction\n")); - goto fail; + goto done; } - TALLOC_FREE(ctx); - return true; + ret = true; + goto done; cancel: + ret = false; if (db->transaction_cancel(db) != 0) { smb_panic("regdb_store_keys: transaction_cancel failed\n"); } -fail: +done: TALLOC_FREE(ctx); - return false; + return ret; } bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) -- cgit From f93c9e0d415b5c2e2fd73bb370db7b7e17ede9aa Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 00:21:46 +0200 Subject: s3:registry: don't leak to talloc_stack in regdb_store_keys_internal2() and catch one potential talloc failure. Michael --- source3/registry/reg_backend_db.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 542f6dc7d0..6bf98d4c75 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -623,14 +623,21 @@ static WERROR regdb_store_keys_internal2(struct db_context *db, WERROR werr; if (!key) { - return WERR_INVALID_PARAM; + werr = WERR_INVALID_PARAM; + goto done; } keyname = talloc_strdup(ctx, key); if (!keyname) { - return WERR_NOMEM; + werr = WERR_NOMEM; + goto done; } + keyname = normalize_reg_path(ctx, keyname); + if (!keyname) { + werr = WERR_NOMEM; + goto done; + } /* allocate some initial memory */ -- cgit From 86d747e19f877c45ac32663ec2a3381ad03cdcf5 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 10:28:29 +0200 Subject: s3:registry: use transaction wrapper in regdb_store_keys_internal(). Michael --- source3/registry/reg_backend_db.c | 198 ++++++++++++++++++++------------------ 1 file changed, 102 insertions(+), 96 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 6bf98d4c75..5c714a40b4 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -725,76 +725,32 @@ done: do not currently exist ***********************************************************************/ -static bool regdb_store_keys_internal(struct db_context *db, const char *key, - struct regsubkey_ctr *ctr) +struct regdb_store_keys_context { + const char *key; + struct regsubkey_ctr *ctr; +}; + +static NTSTATUS regdb_store_keys_action(struct db_context *db, + void *private_data) { - int num_subkeys, old_num_subkeys, i; + struct regdb_store_keys_context *store_ctx; + WERROR werr; + int num_subkeys, i; char *path = NULL; struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL; char *oldkeyname = NULL; - TALLOC_CTX *ctx = talloc_stackframe(); - WERROR werr; - bool ret = false; - - if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) { - goto done; - } - - /* - * fetch a list of the old subkeys so we can determine if anything has - * changed - */ - - werr = regsubkey_ctr_init(ctx, &old_subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - goto done; - } - - regdb_fetch_keys_internal(db, key, old_subkeys); - - num_subkeys = regsubkey_ctr_numkeys(ctr); - old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); - if ((num_subkeys && old_num_subkeys) && - (num_subkeys == old_num_subkeys)) { - - for (i = 0; i < num_subkeys; i++) { - if (strcmp(regsubkey_ctr_specific_key(ctr, i), - regsubkey_ctr_specific_key(old_subkeys, i)) - != 0) - { - break; - } - } - if (i == num_subkeys) { - /* - * Nothing changed, no point to even start a tdb - * transaction - */ - - ret = true; - goto done; - } - } - - TALLOC_FREE(old_subkeys); + TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (db->transaction_start(db) != 0) { - DEBUG(0, ("regdb_store_keys: transaction_start failed\n")); - goto done; - } + store_ctx = (struct regdb_store_keys_context *)private_data; /* * Re-fetch the old keys inside the transaction */ - werr = regsubkey_ctr_init(ctx, &old_subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - goto cancel; - } + werr = regsubkey_ctr_init(mem_ctx, &old_subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); - regdb_fetch_keys_internal(db, key, old_subkeys); + regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys); /* * Make the store operation as safe as possible without transactions: @@ -823,21 +779,22 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, for (i=0; ictr, oldkeyname)) { /* * It's still around, don't delete */ - continue; } - path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname); + path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key, + oldkeyname); if (!path) { - goto cancel; + werr = WERR_NOMEM; + goto done; } werr = regdb_delete_key_lists(db, path); - W_ERROR_NOT_OK_GOTO(werr, cancel); + W_ERROR_NOT_OK_GOTO_DONE(werr); TALLOC_FREE(path); } @@ -846,47 +803,41 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, /* (2) store the subkey list for the parent */ - werr = regdb_store_keys_internal2(db, key, ctr); + werr = regdb_store_keys_internal2(db, store_ctx->key, store_ctx->ctr); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " - "for parent [%s]: %s\n", key, win_errstr(werr))); - goto cancel; + "for parent [%s]: %s\n", store_ctx->key, + win_errstr(werr))); + goto done; } /* (3) now create records for any subkeys that don't already exist */ - num_subkeys = regsubkey_ctr_numkeys(ctr); + num_subkeys = regsubkey_ctr_numkeys(store_ctx->ctr); if (num_subkeys == 0) { - werr = regsubkey_ctr_init(ctx, &subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - goto cancel; - } + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); - werr = regdb_store_keys_internal2(db, key, subkeys); + werr = regdb_store_keys_internal2(db, store_ctx->key, subkeys); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: Failed to store " - "new record for key [%s]: %s\n", key, - win_errstr(werr))); - goto cancel; + "new record for key [%s]: %s\n", + store_ctx->key, win_errstr(werr))); + goto done; } TALLOC_FREE(subkeys); - } for (i=0; ikey, + regsubkey_ctr_specific_key(store_ctx->ctr, i)); if (!path) { - goto cancel; - } - werr = regsubkey_ctr_init(ctx, &subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - goto cancel; + werr = WERR_NOMEM; + goto done; } + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); if (regdb_fetch_keys_internal(db, path, subkeys) == -1) { /* create a record with 0 subkeys */ @@ -895,7 +846,7 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]: %s\n", path, win_errstr(werr))); - goto cancel; + goto done; } } @@ -903,20 +854,75 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, TALLOC_FREE(path); } - if (db->transaction_commit(db) != 0) { - DEBUG(0, ("regdb_store_keys: Could not commit transaction\n")); + werr = WERR_OK; + +done: + talloc_free(mem_ctx); + return werror_to_ntstatus(werr); +} + +static bool regdb_store_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr) +{ + int num_subkeys, old_num_subkeys, i; + struct regsubkey_ctr *old_subkeys = NULL; + TALLOC_CTX *ctx = talloc_stackframe(); + WERROR werr; + bool ret = false; + struct regdb_store_keys_context store_ctx; + + if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) { goto done; } - ret = true; - goto done; + /* + * fetch a list of the old subkeys so we can determine if anything has + * changed + */ -cancel: - ret = false; - if (db->transaction_cancel(db) != 0) { - smb_panic("regdb_store_keys: transaction_cancel failed\n"); + werr = regsubkey_ctr_init(ctx, &old_subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("regdb_store_keys: talloc() failure!\n")); + goto done; } + regdb_fetch_keys_internal(db, key, old_subkeys); + + num_subkeys = regsubkey_ctr_numkeys(ctr); + old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); + if ((num_subkeys && old_num_subkeys) && + (num_subkeys == old_num_subkeys)) { + + for (i = 0; i < num_subkeys; i++) { + if (strcmp(regsubkey_ctr_specific_key(ctr, i), + regsubkey_ctr_specific_key(old_subkeys, i)) + != 0) + { + break; + } + } + if (i == num_subkeys) { + /* + * Nothing changed, no point to even start a tdb + * transaction + */ + + ret = true; + goto done; + } + } + + TALLOC_FREE(old_subkeys); + + store_ctx.key = key; + store_ctx.ctr = ctr; + + werr = ntstatus_to_werror(dbwrap_trans_do(db, + regdb_store_keys_action, + &store_ctx)); + + ret = W_ERROR_IS_OK(werr); + done: TALLOC_FREE(ctx); -- cgit From 8c7b9604931a787107bc01b359a231d376ed92c0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 10:41:59 +0200 Subject: s3:registry: use transaction wrapper in regdb_create_subkey() Michael --- source3/registry/reg_backend_db.c | 73 ++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 5c714a40b4..08d72c3215 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -934,66 +934,77 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) return regdb_store_keys_internal(regdb, key, ctr); } -static WERROR regdb_create_subkey(const char *key, const char *subkey) +struct regdb_create_subkey_context { + const char *key; + const char *subkey; +}; + +static NTSTATUS regdb_create_subkey_action(struct db_context *db, + void *private_data) { WERROR werr; + struct regdb_create_subkey_context *create_ctx; struct regsubkey_ctr *subkeys; TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { - werr = WERR_NOT_FOUND; - goto done; - } + create_ctx = (struct regdb_create_subkey_context *)private_data; werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { + if (regdb_fetch_keys_internal(db, create_ctx->key, subkeys) < 0) { werr = WERR_REG_IO_FAILURE; goto done; } - if (regsubkey_ctr_key_exists(subkeys, subkey)) { - werr = WERR_OK; - goto done; + werr = regsubkey_ctr_addkey(subkeys, create_ctx->subkey); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + werr = regdb_store_keys_internal2(db, create_ctx->key, subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, (__location__ " failed to store new subkey list for " + "parent key %s: %s\n", create_ctx->key, + win_errstr(werr))); } - talloc_free(subkeys); +done: + talloc_free(mem_ctx); + return werror_to_ntstatus(werr); +} - if (regdb->transaction_start(regdb) != 0) { - werr = WERR_REG_IO_FAILURE; +static WERROR regdb_create_subkey(const char *key, const char *subkey) +{ + WERROR werr; + struct regsubkey_ctr *subkeys; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + struct regdb_create_subkey_context create_ctx; + + if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { + werr = WERR_NOT_FOUND; goto done; } werr = regsubkey_ctr_init(mem_ctx, &subkeys); - W_ERROR_NOT_OK_GOTO(werr, cancel); + W_ERROR_NOT_OK_GOTO_DONE(werr); if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { werr = WERR_REG_IO_FAILURE; - goto cancel; + goto done; } - werr = regsubkey_ctr_addkey(subkeys, subkey); - W_ERROR_NOT_OK_GOTO(werr, cancel); - - werr = regdb_store_keys_internal2(regdb, key, subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " failed to store new subkey list for " - "parent key %s: %s\n", key, win_errstr(werr))); - goto cancel; + if (regsubkey_ctr_key_exists(subkeys, subkey)) { + werr = WERR_OK; + goto done; } - if (regdb->transaction_commit(regdb) != 0) { - werr = WERR_REG_IO_FAILURE; - DEBUG(0, (__location__ " failed to commit transaction\n")); - } + talloc_free(subkeys); - goto done; + create_ctx.key = key; + create_ctx.subkey = subkey; -cancel: - if (regdb->transaction_cancel(regdb) != 0) { - smb_panic("regdb_create_subkey: transaction_cancel failed\n"); - } + werr = ntstatus_to_werror(dbwrap_trans_do(regdb, + regdb_create_subkey_action, + &create_ctx)); done: talloc_free(mem_ctx); -- cgit From 5640598cbb66fb0e65413e53a11ff82a553caad6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 10:52:40 +0200 Subject: s3:registry: add a comment header for the create_subkey set of functions Michael --- source3/registry/reg_backend_db.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 08d72c3215..f60ee1f7a6 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -934,6 +934,10 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) return regdb_store_keys_internal(regdb, key, ctr); } +/** + * create a subkey of a given key + */ + struct regdb_create_subkey_context { const char *key; const char *subkey; -- cgit From a48d8353c79685371dbd2cc73b6c9032c5166a5b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 10:54:18 +0200 Subject: s3:registry: add a comment header for the delete_subkey set of commands. Michael --- source3/registry/reg_backend_db.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index f60ee1f7a6..8cd79b15b2 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1015,6 +1015,10 @@ done: return werr; } +/** + * create a subkey of a given key + */ + static WERROR regdb_delete_subkey(const char *key, const char *subkey) { WERROR werr; -- cgit From 2d6dbcd0b13da469f8b7dc6ed65e51d91ce1ab9c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 11:04:20 +0200 Subject: s3:registry: use transaction wrapper in regdb_delete_subkey(). Michael --- source3/registry/reg_backend_db.c | 86 ++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 8cd79b15b2..095b0c5b22 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1019,11 +1019,53 @@ done: * create a subkey of a given key */ -static WERROR regdb_delete_subkey(const char *key, const char *subkey) +struct regdb_delete_subkey_context { + const char *key; + const char *subkey; + const char *path; +}; + +static NTSTATUS regdb_delete_subkey_action(struct db_context *db, + void *private_data) { WERROR werr; + struct regdb_delete_subkey_context *delete_ctx; struct regsubkey_ctr *subkeys; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + delete_ctx = (struct regdb_delete_subkey_context *)private_data; + + werr = regdb_delete_key_lists(db, delete_ctx->path); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + if (regdb_fetch_keys_internal(db, delete_ctx->key, subkeys) < 0) { + werr = WERR_REG_IO_FAILURE; + goto done; + } + + werr = regsubkey_ctr_delkey(subkeys, delete_ctx->subkey); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + werr = regdb_store_keys_internal2(db, delete_ctx->key, subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, (__location__ " failed to store new subkey_list for " + "parent key %s: %s\n", delete_ctx->key, + win_errstr(werr))); + } + +done: + talloc_free(mem_ctx); + return werror_to_ntstatus(werr); +} + +static WERROR regdb_delete_subkey(const char *key, const char *subkey) +{ + WERROR werr; char *path; + struct regdb_delete_subkey_context delete_ctx; TALLOC_CTX *mem_ctx = talloc_stackframe(); if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { @@ -1042,43 +1084,13 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) goto done; } - if (regdb->transaction_start(regdb) != 0) { - werr = WERR_REG_IO_FAILURE; - goto done; - } - - werr = regdb_delete_key_lists(regdb, path); - W_ERROR_NOT_OK_GOTO(werr, cancel); - - werr = regsubkey_ctr_init(mem_ctx, &subkeys); - W_ERROR_NOT_OK_GOTO(werr, cancel); - - if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { - werr = WERR_REG_IO_FAILURE; - goto cancel; - } - - werr = regsubkey_ctr_delkey(subkeys, subkey); - W_ERROR_NOT_OK_GOTO(werr, cancel); - - werr = regdb_store_keys_internal2(regdb, key, subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " failed to store new subkey_list for " - "parent key %s: %s\n", key, win_errstr(werr))); - goto cancel; - } - - if (regdb->transaction_commit(regdb) != 0) { - DEBUG(0, (__location__ " failed to commit transaction\n")); - werr = WERR_REG_IO_FAILURE; - } + delete_ctx.key = key; + delete_ctx.subkey = subkey; + delete_ctx.path = path; - goto done; - -cancel: - if (regdb->transaction_cancel(regdb) != 0) { - smb_panic("regdb_delete_subkey: transaction_cancel failed\n"); - } + werr = ntstatus_to_werror(dbwrap_trans_do(regdb, + regdb_delete_subkey_action, + &delete_ctx)); done: talloc_free(mem_ctx); -- cgit From 109ea29b2c1a3bc752f9afda2c0010b9e675aa83 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 12:54:16 +0200 Subject: s3:registry: restructure logic of create_sorted_subkes() slightly This makes it clearer to me, and it also makes it easier to use the transaction retry wrapper in the next step. Michael --- source3/registry/reg_backend_db.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 095b0c5b22..e0e234f7c6 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1195,18 +1195,18 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) werr = regsubkey_ctr_init(talloc_tos(), &ctr); if (!W_ERROR_IS_OK(werr)) { - goto fail; + goto commit; } res = regdb_fetch_keys_internal(regdb, key, ctr); if (res == -1) { - goto fail; + goto commit; } num_subkeys = regsubkey_ctr_numkeys(ctr); sorted_subkeys = talloc_array(ctr, char *, num_subkeys); if (sorted_subkeys == NULL) { - goto fail; + goto commit; } len = 4 + 4*num_subkeys; @@ -1215,7 +1215,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys, regsubkey_ctr_specific_key(ctr, i)); if (sorted_subkeys[i] == NULL) { - goto fail; + goto commit; } len += strlen(sorted_subkeys[i])+1; } @@ -1224,7 +1224,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) buf = talloc_array(ctr, char, len); if (buf == NULL) { - goto fail; + goto commit; } p = buf + 4 + 4*num_subkeys; @@ -1242,21 +1242,17 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { /* - * Don't use a "goto fail;" here, this would commit the broken + * Don't use a "goto commit;" here, this would commit the broken * transaction. See below for an explanation. */ - if (regdb->transaction_cancel(regdb) == -1) { - smb_panic("create_sorted_subkeys: transaction_cancel " - "failed\n"); - } - TALLOC_FREE(ctr); - return false; + goto cancel; } result = true; - fail: + +commit: /* - * We only get here via the "goto fail" when we did not write anything + * We only get here via the "goto commit" when we did not write anything * yet. Using transaction_commit even in a failure case is necessary * because this (disposable) call might be nested in other * transactions. Doing a cancel here would destroy the possibility of @@ -1267,7 +1263,16 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) "failed\n")); result = false; } + goto done; + +cancel: + if (regdb->transaction_cancel(regdb) == -1) { + smb_panic("create_sorted_subkeys: transaction_cancel " + "failed\n"); + } + result = false; +done: TALLOC_FREE(ctr); return result; } -- cgit From c52dd1d5b81ce71855a3215f1b23704ac450fdee Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 13 Jul 2009 17:15:14 +0200 Subject: s3:registry: use transaction wrapper in create_sorted_subkeys() Michael --- source3/registry/reg_backend_db.c | 99 ++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index e0e234f7c6..11e6f66760 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1174,39 +1174,55 @@ static int cmp_keynames(const void *p1, const void *p2) return StrCaseCmp(*((char **)p1), *((char **)p2)); } -static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) +struct create_sorted_subkeys_context { + const char *key; + const char *sorted_keyname; +}; + +static NTSTATUS create_sorted_subkeys_action(struct db_context *db, + void *private_data) { char **sorted_subkeys; struct regsubkey_ctr *ctr; - bool result = false; NTSTATUS status; char *buf; char *p; int i, res; size_t len; int num_subkeys; - WERROR werr; + struct create_sorted_subkeys_context *sorted_ctx; - if (regdb->transaction_start(regdb) != 0) { - DEBUG(0, ("create_sorted_subkeys: transaction_start " - "failed\n")); - return false; - } + sorted_ctx = (struct create_sorted_subkeys_context *)private_data; - werr = regsubkey_ctr_init(talloc_tos(), &ctr); - if (!W_ERROR_IS_OK(werr)) { - goto commit; + /* + * In this function, we only treat failing of the actual write to + * the db as a real error. All preliminary errors, at a stage when + * nothing has been written to the DB yet are treated as success + * to be committed (as an empty transaction). + * + * The reason is that this (disposable) call might be nested in other + * transactions. Doing a cancel here would destroy the possibility of + * a transaction_commit for transactions that we might be wrapped in. + */ + + status = werror_to_ntstatus(regsubkey_ctr_init(talloc_tos(), &ctr)); + if (!NT_STATUS_IS_OK(status)) { + /* don't treat this as an error */ + status = NT_STATUS_OK; + goto done; } - res = regdb_fetch_keys_internal(regdb, key, ctr); + res = regdb_fetch_keys_internal(db, sorted_ctx->key, ctr); if (res == -1) { - goto commit; + /* don't treat this as an error */ + goto done; } num_subkeys = regsubkey_ctr_numkeys(ctr); sorted_subkeys = talloc_array(ctr, char *, num_subkeys); if (sorted_subkeys == NULL) { - goto commit; + /* don't treat this as an error */ + goto done; } len = 4 + 4*num_subkeys; @@ -1215,7 +1231,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys, regsubkey_ctr_specific_key(ctr, i)); if (sorted_subkeys[i] == NULL) { - goto commit; + /* don't treat this as an error */ + goto done; } len += strlen(sorted_subkeys[i])+1; } @@ -1224,7 +1241,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) buf = talloc_array(ctr, char, len); if (buf == NULL) { - goto commit; + /* don't treat this as an error */ + goto done; } p = buf + 4 + 4*num_subkeys; @@ -1238,43 +1256,28 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) } status = dbwrap_store_bystring( - regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len), + db, sorted_ctx->sorted_keyname, make_tdb_data((uint8_t *)buf, + len), TDB_REPLACE); - if (!NT_STATUS_IS_OK(status)) { - /* - * Don't use a "goto commit;" here, this would commit the broken - * transaction. See below for an explanation. - */ - goto cancel; - } - result = true; +done: + talloc_free(ctr); + return status; +} -commit: - /* - * We only get here via the "goto commit" when we did not write anything - * yet. Using transaction_commit even in a failure case is necessary - * because this (disposable) call might be nested in other - * transactions. Doing a cancel here would destroy the possibility of - * a transaction_commit for transactions that we might be wrapped in. - */ - if (regdb->transaction_commit(regdb) == -1) { - DEBUG(0, ("create_sorted_subkeys: transaction_commit " - "failed\n")); - result = false; - } - goto done; +static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) +{ + NTSTATUS status; + struct create_sorted_subkeys_context sorted_ctx; -cancel: - if (regdb->transaction_cancel(regdb) == -1) { - smb_panic("create_sorted_subkeys: transaction_cancel " - "failed\n"); - } - result = false; + sorted_ctx.key = key; + sorted_ctx.sorted_keyname = sorted_keyname; -done: - TALLOC_FREE(ctr); - return result; + status = dbwrap_trans_do(regdb, + create_sorted_subkeys_action, + &sorted_ctx); + + return NT_STATUS_IS_OK(status); } struct scan_subkey_state { -- cgit From dc0bcfa188cb24c5a34f592ece946682d5fb8afe Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 12:45:43 +0200 Subject: s3:registry: turn regdb_fetch_keys_internal() from int to WERROR return type This way, more error information is propagated to the callers. Michael --- source3/registry/reg_backend_db.c | 85 ++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 11e6f66760..7825edd5c2 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -29,8 +29,8 @@ static int regdb_refcount; static bool regdb_key_exists(struct db_context *db, const char *key); static bool regdb_key_is_base_key(const char *key); -static int regdb_fetch_keys_internal(struct db_context *db, const char *key, - struct regsubkey_ctr *ctr); +static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr); static bool regdb_store_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); static int regdb_fetch_values_internal(struct db_context *db, const char* key, @@ -182,7 +182,13 @@ static WERROR init_registry_key_internal(struct db_context *db, goto fail; } - regdb_fetch_keys_internal(db, base, subkeys); + werr = regdb_fetch_keys_internal(db, base, subkeys); + if (!W_ERROR_IS_OK(werr) && + !W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) + { + goto fail; + } + if (*subkeyname) { werr = regsubkey_ctr_addkey(subkeys, subkeyname); if (!W_ERROR_IS_OK(werr)) { @@ -750,7 +756,12 @@ static NTSTATUS regdb_store_keys_action(struct db_context *db, werr = regsubkey_ctr_init(mem_ctx, &old_subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys); + werr = regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys); + if (!W_ERROR_IS_OK(werr) && + !W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) + { + goto done; + } /* * Make the store operation as safe as possible without transactions: @@ -839,7 +850,8 @@ static NTSTATUS regdb_store_keys_action(struct db_context *db, werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys_internal(db, path, subkeys) == -1) { + werr = regdb_fetch_keys_internal(db, path, subkeys); + if (!W_ERROR_IS_OK(werr)) { /* create a record with 0 subkeys */ werr = regdb_store_keys_internal2(db, path, subkeys); if (!W_ERROR_IS_OK(werr)) { @@ -886,7 +898,12 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, goto done; } - regdb_fetch_keys_internal(db, key, old_subkeys); + werr = regdb_fetch_keys_internal(db, key, old_subkeys); + if (!W_ERROR_IS_OK(werr) && + !W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) + { + goto done; + } num_subkeys = regsubkey_ctr_numkeys(ctr); old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); @@ -956,10 +973,8 @@ static NTSTATUS regdb_create_subkey_action(struct db_context *db, werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys_internal(db, create_ctx->key, subkeys) < 0) { - werr = WERR_REG_IO_FAILURE; - goto done; - } + werr = regdb_fetch_keys_internal(db, create_ctx->key, subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); werr = regsubkey_ctr_addkey(subkeys, create_ctx->subkey); W_ERROR_NOT_OK_GOTO_DONE(werr); @@ -991,10 +1006,8 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { - werr = WERR_REG_IO_FAILURE; - goto done; - } + werr = regdb_fetch_keys_internal(regdb, key, subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); if (regsubkey_ctr_key_exists(subkeys, subkey)) { werr = WERR_OK; @@ -1041,10 +1054,8 @@ static NTSTATUS regdb_delete_subkey_action(struct db_context *db, werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys_internal(db, delete_ctx->key, subkeys) < 0) { - werr = WERR_REG_IO_FAILURE; - goto done; - } + werr = regdb_fetch_keys_internal(db, delete_ctx->key, subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); werr = regsubkey_ctr_delkey(subkeys, delete_ctx->subkey); W_ERROR_NOT_OK_GOTO_DONE(werr); @@ -1187,7 +1198,7 @@ static NTSTATUS create_sorted_subkeys_action(struct db_context *db, NTSTATUS status; char *buf; char *p; - int i, res; + int i; size_t len; int num_subkeys; struct create_sorted_subkeys_context *sorted_ctx; @@ -1212,9 +1223,12 @@ static NTSTATUS create_sorted_subkeys_action(struct db_context *db, goto done; } - res = regdb_fetch_keys_internal(db, sorted_ctx->key, ctr); - if (res == -1) { + status = werror_to_ntstatus(regdb_fetch_keys_internal(db, + sorted_ctx->key, + ctr)); + if (!NT_STATUS_IS_OK(status)) { /* don't treat this as an error */ + status = NT_STATUS_OK; goto done; } @@ -1423,36 +1437,36 @@ done: released by the caller. ***********************************************************************/ -static int regdb_fetch_keys_internal(struct db_context *db, const char *key, - struct regsubkey_ctr *ctr) +static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr) { WERROR werr; - uint32 num_items; + uint32_t num_items; uint8 *buf; uint32 buflen, len; int i; fstring subkeyname; - int ret = -1; TALLOC_CTX *frame = talloc_stackframe(); TDB_DATA value; DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL")); + frame = talloc_stackframe(); + if (!regdb_key_exists(db, key)) { + DEBUG(10, ("key [%s] not found\n", key)); + werr = WERR_NOT_FOUND; goto done; } werr = regsubkey_ctr_set_seqnum(ctr, db->get_seqnum(db)); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } + W_ERROR_NOT_OK_GOTO_DONE(werr); value = regdb_fetch_key_internal(db, frame, key); if (value.dptr == NULL) { DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n", key)); - ret = 0; goto done; } @@ -1466,21 +1480,28 @@ static int regdb_fetch_keys_internal(struct db_context *db, const char *key, if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey " "failed: %s\n", win_errstr(werr))); + num_items = 0; goto done; } } DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items)); - ret = num_items; done: TALLOC_FREE(frame); - return ret; + return werr; } int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) { - return regdb_fetch_keys_internal(regdb, key, ctr); + WERROR werr; + + werr = regdb_fetch_keys_internal(regdb, key, ctr); + if (!W_ERROR_IS_OK(werr)) { + return -1; + } + + return regsubkey_ctr_numkeys(ctr); } /**************************************************************************** -- cgit From 92df5e4a0243bde6fbc5261bf6758090c4c35eee Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 12:47:12 +0200 Subject: s3:registry: add function regsubkey_ctr_reinit() This reinitializes an already allocated regsubkey_ctr structure, emptying out the subkey array and hash table. Michael --- source3/include/proto.h | 1 + source3/registry/reg_objects.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 56bffd5ce7..7bbdc04ae7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5097,6 +5097,7 @@ WERROR registry_init_smbconf(const char *keyname); /* The following definitions come from registry/reg_objects.c */ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr); +WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr); WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum); int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr); WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ); diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index a592c76e1d..0c0455aada 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -63,6 +63,29 @@ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr) return WERR_OK; } +/** + * re-initialize the list of subkeys (to the emtpy list) + * in an already allocated regsubkey_ctr + */ + +WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr) +{ + if (ctr == NULL) { + return WERR_INVALID_PARAM; + } + + talloc_free(ctr->subkeys_hash); + ctr->subkeys_hash = db_open_rbt(ctr); + W_ERROR_HAVE_NO_MEMORY(ctr->subkeys_hash); + + TALLOC_FREE(ctr->subkeys); + + ctr->num_subkeys = 0; + ctr->seqnum = 0; + + return WERR_OK; +} + WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum) { if (ctr == NULL) { -- cgit From 78576117eb4292e4e2750928d5f84c2edc94192f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 12:50:55 +0200 Subject: s3:registry: flush the provided subkey_ctr in regdb_fetch_keys_internal() This way, we always return what has really been read from the db, and not more. The callers assume exactly this, but one could hand in an already pre-filled subkey container... Michael --- source3/registry/reg_backend_db.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 7825edd5c2..9fd5c3161b 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1474,6 +1474,9 @@ static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key, buflen = value.dsize; len = tdb_unpack( buf, buflen, "d", &num_items); + werr = regsubkey_ctr_reinit(ctr); + W_ERROR_NOT_OK_GOTO_DONE(werr); + for (i=0; i Date: Tue, 7 Jul 2009 17:16:21 +0200 Subject: s3:registry: db backend: add my C Michael --- source3/registry/reg_backend_db.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 9fd5c3161b..dec43ae741 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -2,6 +2,7 @@ * Unix SMB/CIFS implementation. * Virtual Windows Registry Layer * Copyright (C) Gerald Carter 2002-2005 + * Copyright (C) Michael Adam 2007-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 -- cgit From 7bd4699228a1975573cb62550043c05b48e66361 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 16:59:07 +0200 Subject: s3:dbwrap: fix embarrassing typo :-) Michael --- source3/lib/dbwrap_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 6c95672986..7dbeb63927 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. Utility functions for the dbwrap API Copyright (C) Volker Lendecke 2007 - Copyrithg (C) Michael Adam 2009 + Copyright (C) Michael Adam 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 -- cgit From 2df4550aae1e326511fe4e7e0d2d98be3e578caf Mon Sep 17 00:00:00 2001 From: Peter Volkov Date: Wed, 15 Jul 2009 17:36:25 +0200 Subject: s3: make linking of cifs.upcall --as-needed safe See http://www.gentoo.org/proj/en/qa/asneeded.xml for details. --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index bc00f6a863..8b78984b8d 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1517,7 +1517,7 @@ bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ) bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@ @echo Linking $@ @$(CC) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \ - -lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ1) $(KRB5LIBS) \ + $(LIBSMBCLIENT_OBJ1) $(LIBS) -lkeyutils $(KRB5LIBS) \ $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBWBCLIENT_LIBS) \ $(LIBTDB_LIBS) $(NSCD_LIBS) $(ZLIB_LIBS) -- cgit From 5236b3699da2b5cc55d55310de76e4ab65a8bb46 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Wed, 15 Jul 2009 17:24:14 +0200 Subject: s3: make linking of rpcclient --as-needed safe --- source3/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 8b78984b8d..f6396ef157 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1476,10 +1476,10 @@ bin/swat@EXEEXT@: $(BINARY_PREREQS) $(SWAT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ bin/rpcclient@EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@ @echo Linking $@ - @$(CC) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \ + @$(CC) -o $@ $(LDFLAGS) $(RPCCLIENT_OBJ) \ $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) $(POPT_LIBS) \ $(KRB5LIBS) $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ - $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) + $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) $(PASSDB_LIBS) bin/smbclient@EXEEXT@: $(BINARY_PREREQS) $(CLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@ @echo Linking $@ -- cgit From b08ca108ef8d483e77481ca3335599762cb2547c Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Wed, 15 Jul 2009 18:32:58 +0200 Subject: Ñ•4:heimdal: teach heimdal that we have strnlen via libreplcae MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source4/heimdal_build/roken.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/heimdal_build/roken.h b/source4/heimdal_build/roken.h index 4eabbe2af4..5cb47e8ba6 100644 --- a/source4/heimdal_build/roken.h +++ b/source4/heimdal_build/roken.h @@ -37,6 +37,10 @@ #define HAVE_SETEUID 1 #endif +#ifndef HAVE_STRNLEN +#define HAVE_STRNLEN +#endif + #ifndef HAVE_STRNDUP #define HAVE_STRNDUP #endif -- cgit From 382d5c8f5bb3b54e7c1a2daaf9d0283b6275768a Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Wed, 15 Jul 2009 18:40:57 +0200 Subject: s4:heimdal: teach heimdal we have (v)aÑ•printf in libreplace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source4/heimdal_build/roken.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/heimdal_build/roken.h b/source4/heimdal_build/roken.h index 5cb47e8ba6..decce03522 100644 --- a/source4/heimdal_build/roken.h +++ b/source4/heimdal_build/roken.h @@ -57,6 +57,14 @@ #define HAVE_STRCASECMP #endif +#ifndef HAVE_ASPRINTF +#define HAVE_ASPRINTF +#endif + +#ifndef HAVE_VASPRINTF +#define HAVE_VASPRINTF +#endif + #ifndef HAVE_MKSTEMP #define HAVE_MKSTEMP #endif -- cgit From 5240b10eaa1f19dcf2dbc31e5e1f8868716bbc69 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 19:17:57 +0200 Subject: s3:ntvfs/posix: avoid unnesessary talloc_reference() This caused the panics on the RAW-SETFILEINFO.RENAME test, because we returned an empty strings. The problem was: ERROR: talloc_steal with references at ntvfs/posix/pvfs_setfileinfo.c:215 reference at ntvfs/posix/pvfs_resolve.c:799 metze --- source4/ntvfs/posix/pvfs_resolve.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index c33323350e..8e8da72e1f 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -796,7 +796,10 @@ NTSTATUS pvfs_resolve_parent(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, (*name)->has_wildcard = false; /* we can't get the correct 'original_name', but for the purposes of this call this is close enough */ - (*name)->original_name = talloc_reference(*name, child->original_name); + (*name)->original_name = talloc_strdup(*name, child->original_name); + if ((*name)->original_name == NULL) { + return NT_STATUS_NO_MEMORY; + } (*name)->stream_name = NULL; (*name)->stream_id = 0; -- cgit From 64ee4458cf8c8fb1dec5334cebbe63cfb0045ada Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 19:23:12 +0200 Subject: s4:ntvfs/ipc: replace unnesessary talloc_reference() by a simple talloc_strdup() metze --- source4/ntvfs/ipc/vfs_ipc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 20b00f24e3..95ad1c51fb 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -258,7 +258,8 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, one of the interfaces attached to this pipe endpoint. */ ep_description->transport = NCACN_NP; - ep_description->endpoint = talloc_reference(ep_description, p->pipe_name); + ep_description->endpoint = talloc_strdup(ep_description, p->pipe_name); + NT_STATUS_HAVE_NO_MEMORY(ep_description->endpoint); /* The session info is refcount-increased in the * dcesrv_endpoint_search_connect() function -- cgit From dea2e4690a188a5ff06c9df354befe65cbcb320c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 20:43:23 +0200 Subject: s4:heimdal_build: try to fix the build on Solaris We need the definition of 'struct flock'. metze --- source4/heimdal_build/replace.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source4/heimdal_build/replace.c b/source4/heimdal_build/replace.c index ba43dd9495..6842b11f96 100644 --- a/source4/heimdal_build/replace.c +++ b/source4/heimdal_build/replace.c @@ -21,11 +21,9 @@ */ #include "config.h" -#include -#include -#include #include "err.h" #include "roken.h" +#include "system/filesys.h" #ifndef HAVE_ERR void err(int eval, const char *format, ...) -- cgit From 722765213bcda1de93d2fe7d64b89c8b7a37f29e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 20:45:53 +0200 Subject: s4:libnet: rename uint => uint32_t because uint is not portable metze --- source4/libnet/libnet_group.c | 2 +- source4/libnet/libnet_group.h | 4 ++-- source4/libnet/libnet_user.c | 2 +- source4/libnet/libnet_user.h | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source4/libnet/libnet_group.c b/source4/libnet/libnet_group.c index b0669640f3..9e7abe81b1 100644 --- a/source4/libnet/libnet_group.c +++ b/source4/libnet/libnet_group.c @@ -484,7 +484,7 @@ struct composite_context *libnet_GroupList_send(struct libnet_context *ctx, /* store the arguments in the state structure */ s->ctx = ctx; s->page_size = io->in.page_size; - s->resume_index = (uint32_t)io->in.resume_index; + s->resume_index = io->in.resume_index; s->domain_name = talloc_strdup(c, io->in.domain_name); s->monitor_fn = monitor; diff --git a/source4/libnet/libnet_group.h b/source4/libnet/libnet_group.h index b80d3449c8..8ac47437fd 100644 --- a/source4/libnet/libnet_group.h +++ b/source4/libnet/libnet_group.h @@ -58,11 +58,11 @@ struct libnet_GroupList { struct { const char *domain_name; int page_size; - uint resume_index; + uint32_t resume_index; } in; struct { int count; - uint resume_index; + uint32_t resume_index; struct grouplist { const char *sid; diff --git a/source4/libnet/libnet_user.c b/source4/libnet/libnet_user.c index 8606d0856e..dd4d501c17 100644 --- a/source4/libnet/libnet_user.c +++ b/source4/libnet/libnet_user.c @@ -945,7 +945,7 @@ struct composite_context* libnet_UserList_send(struct libnet_context *ctx, /* store the arguments in the state structure */ s->ctx = ctx; s->page_size = r->in.page_size; - s->resume_index = (uint32_t)r->in.resume_index; + s->resume_index = r->in.resume_index; s->domain_name = talloc_strdup(c, r->in.domain_name); s->monitor_fn = monitor; diff --git a/source4/libnet/libnet_user.h b/source4/libnet/libnet_user.h index 4aad654b3b..8203d14c33 100644 --- a/source4/libnet/libnet_user.h +++ b/source4/libnet/libnet_user.h @@ -140,11 +140,11 @@ struct libnet_UserList { struct { const char *domain_name; int page_size; - uint resume_index; + uint32_t resume_index; } in; struct { int count; - uint resume_index; + uint32_t resume_index; struct userlist { const char *sid; -- cgit From b76ab511f7238820a4e6ac3a2ae17d103f2bf9b9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 20:47:07 +0200 Subject: s4:winbind: rename uint => uint32_t as uint isn't portable metze --- source4/winbind/wb_cmd_list_users.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/winbind/wb_cmd_list_users.c b/source4/winbind/wb_cmd_list_users.c index f67f133488..755d45786b 100644 --- a/source4/winbind/wb_cmd_list_users.c +++ b/source4/winbind/wb_cmd_list_users.c @@ -33,7 +33,7 @@ struct cmd_list_users_state { struct wbsrv_domain *domain; char *domain_name; - uint resume_index; + uint32_t resume_index; char *result; }; -- cgit From 1f5aec877fc48ff96b14a0e95f01c68a29dd8718 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Jul 2009 11:49:33 -0700 Subject: Make cli_unlock and cli_unlock64 async. Fix POSIX lock test. Jeremy. --- source3/include/proto.h | 18 ++- source3/libsmb/clifile.c | 270 +++++++++++++++++++++++++++++++++----------- source3/torture/locktest.c | 4 +- source3/torture/locktest2.c | 2 +- source3/torture/torture.c | 44 ++++---- 5 files changed, 247 insertions(+), 91 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 7bbdc04ae7..15e3f325aa 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2518,10 +2518,24 @@ NTSTATUS cli_locktype(struct cli_state *cli, uint16_t fnum, int timeout, unsigned char locktype); bool cli_lock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type); -bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len); +struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len); +NTSTATUS cli_unlock_recv(struct tevent_req *req); +NTSTATUS cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len); bool cli_lock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type); -bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); +struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len); +NTSTATUS cli_unlock64_recv(struct tevent_req *req); +NTSTATUS cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 0e2b3640f2..5ea0579839 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1893,7 +1893,6 @@ struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx, SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO); /* Setup param array. */ - memset(state->param, '\0', 6); SSVAL(state->param,0,fnum); SSVAL(state->param,2,SMB_SET_FILE_DISPOSITION_INFO); @@ -2010,6 +2009,7 @@ struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } + vwv = state->vwv; SCVAL(vwv+0, 0, 0xFF); @@ -2367,6 +2367,7 @@ struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } + SSVAL(state->vwv+0, 0, fnum); SIVALS(state->vwv+1, 0, -1); @@ -2708,42 +2709,114 @@ bool cli_lock(struct cli_state *cli, uint16_t fnum, Unlock a file. ****************************************************************************/ -bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len) +struct cli_unlock_state { + uint16_t vwv[8]; + uint8_t data[10]; +}; + +static void cli_unlock_done(struct tevent_req *subreq); + +struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) + { - char *p; + struct tevent_req *req = NULL, *subreq = NULL; + struct cli_unlock_state *state = NULL; + uint8_t additional_flags = 0; - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); + req = tevent_req_create(mem_ctx, &state, struct cli_unlock_state); + if (req == NULL) { + return NULL; + } - cli_set_message(cli->outbuf,8,0,True); + SCVAL(state->vwv+0, 0, 0xFF); + SSVAL(state->vwv+2, 0, fnum); + SCVAL(state->vwv+3, 0, 0); + SIVALS(state->vwv+4, 0, 0); + SSVAL(state->vwv+6, 0, 1); + SSVAL(state->vwv+7, 0, 0); - SCVAL(cli->outbuf,smb_com,SMBlockingX); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + SSVAL(state->data, 0, cli->pid); + SIVAL(state->data, 2, offset); + SIVAL(state->data, 6, len); - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,fnum); - SCVAL(cli->outbuf,smb_vwv3,0); - SIVALS(cli->outbuf, smb_vwv4, 0); - SSVAL(cli->outbuf,smb_vwv6,1); - SSVAL(cli->outbuf,smb_vwv7,0); + subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags, + 8, state->vwv, 10, state->data); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_unlock_done, req); + return req; +} - p = smb_buf(cli->outbuf); - SSVAL(p, 0, cli->pid); - SIVAL(p, 2, offset); - SIVAL(p, 6, len); - p += 10; - cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; +static void cli_unlock_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + NTSTATUS status; + + status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + tevent_req_done(req); +} - if (cli_is_error(cli)) { - return False; +NTSTATUS cli_unlock_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +NTSTATUS cli_unlock(struct cli_state *cli, + uint16_t fnum, + uint32_t offset, + uint32_t len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; } - return True; + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_unlock_send(frame, ev, cli, + fnum, offset, len); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_unlock_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** @@ -2811,46 +2884,118 @@ bool cli_lock64(struct cli_state *cli, uint16_t fnum, Unlock a file with 64 bit offsets. ****************************************************************************/ -bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len) +struct cli_unlock64_state { + uint16_t vwv[8]; + uint8_t data[20]; +}; + +static void cli_unlock64_done(struct tevent_req *subreq); + +struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) + { - char *p; + struct tevent_req *req = NULL, *subreq = NULL; + struct cli_unlock64_state *state = NULL; + uint8_t additional_flags = 0; - if (! (cli->capabilities & CAP_LARGE_FILES)) { - return cli_unlock(cli, fnum, offset, len); + req = tevent_req_create(mem_ctx, &state, struct cli_unlock64_state); + if (req == NULL) { + return NULL; } - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); + SCVAL(state->vwv+0, 0, 0xff); + SSVAL(state->vwv+2, 0, fnum); + SCVAL(state->vwv+3, 0,LOCKING_ANDX_LARGE_FILES); + SIVALS(state->vwv+4, 0, 0); + SSVAL(state->vwv+6, 0, 1); + SSVAL(state->vwv+7, 0, 0); - cli_set_message(cli->outbuf,8,0,True); + SIVAL(state->data, 0, cli->pid); + SOFF_T_R(state->data, 4, offset); + SOFF_T_R(state->data, 12, len); - SCVAL(cli->outbuf,smb_com,SMBlockingX); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags, + 8, state->vwv, 20, state->data); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_unlock64_done, req); + return req; +} - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,fnum); - SCVAL(cli->outbuf,smb_vwv3,LOCKING_ANDX_LARGE_FILES); - SIVALS(cli->outbuf, smb_vwv4, 0); - SSVAL(cli->outbuf,smb_vwv6,1); - SSVAL(cli->outbuf,smb_vwv7,0); +static void cli_unlock64_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + NTSTATUS status; - p = smb_buf(cli->outbuf); - SIVAL(p, 0, cli->pid); - SOFF_T_R(p, 4, offset); - SOFF_T_R(p, 12, len); - p += 20; - cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; + status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + tevent_req_done(req); +} - if (cli_is_error(cli)) { - return False; +NTSTATUS cli_unlock64_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +NTSTATUS cli_unlock64(struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_OK; + + if (! (cli->capabilities & CAP_LARGE_FILES)) { + return cli_unlock(cli, fnum, offset, len); } - return True; + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_unlock64_send(frame, ev, cli, + fnum, offset, len); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_unlock64_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** @@ -3421,7 +3566,7 @@ NTSTATUS cli_getatr(struct cli_state *cli, static void cli_setattrE_done(struct tevent_req *subreq); struct cli_setattrE_state { - int dummy; + uint16_t vwv[7]; }; struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx, @@ -3435,21 +3580,19 @@ struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx, struct tevent_req *req = NULL, *subreq = NULL; struct cli_setattrE_state *state = NULL; uint8_t additional_flags = 0; - uint16_t vwv[7]; req = tevent_req_create(mem_ctx, &state, struct cli_setattrE_state); if (req == NULL) { return NULL; } - memset(vwv, '\0', sizeof(vwv)); - SSVAL(vwv+0, 0, fnum); - cli_put_dos_date2(cli, (char *)&vwv[1], 0, change_time); - cli_put_dos_date2(cli, (char *)&vwv[3], 0, access_time); - cli_put_dos_date2(cli, (char *)&vwv[5], 0, write_time); + SSVAL(state->vwv+0, 0, fnum); + cli_put_dos_date2(cli, (char *)&state->vwv[1], 0, change_time); + cli_put_dos_date2(cli, (char *)&state->vwv[3], 0, access_time); + cli_put_dos_date2(cli, (char *)&state->vwv[5], 0, write_time); subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags, - 7, vwv, 0, NULL); + 7, state->vwv, 0, NULL); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -3556,7 +3699,6 @@ struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx, return NULL; } - memset(state->vwv, '\0', sizeof(state->vwv)); SSVAL(state->vwv+0, 0, attr); cli_put_dos_date3(cli, (char *)&state->vwv[1], 0, mtime); diff --git a/source3/torture/locktest.c b/source3/torture/locktest.c index 30b84c073d..a90c2e2dfe 100644 --- a/source3/torture/locktest.c +++ b/source3/torture/locktest.c @@ -341,9 +341,9 @@ static bool test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS], case OP_UNLOCK: /* unset a lock */ for (server=0;server Date: Wed, 15 Jul 2009 20:54:01 +0200 Subject: s3:tldap: fix the build - a void function should not return a value metze --- source3/lib/tldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c index 451bc18d2e..fa56763a33 100644 --- a/source3/lib/tldap.c +++ b/source3/lib/tldap.c @@ -1618,7 +1618,7 @@ struct tevent_req *tldap_add_send(TALLOC_CTX *mem_ctx, static void tldap_add_done(struct tevent_req *subreq) { - return tldap_simple_done(subreq, TLDAP_RES_ADD); + tldap_simple_done(subreq, TLDAP_RES_ADD); } int tldap_add_recv(struct tevent_req *req) @@ -1718,7 +1718,7 @@ struct tevent_req *tldap_modify_send(TALLOC_CTX *mem_ctx, static void tldap_modify_done(struct tevent_req *subreq) { - return tldap_simple_done(subreq, TLDAP_RES_MODIFY); + tldap_simple_done(subreq, TLDAP_RES_MODIFY); } int tldap_modify_recv(struct tevent_req *req) @@ -1795,7 +1795,7 @@ struct tevent_req *tldap_delete_send(TALLOC_CTX *mem_ctx, static void tldap_delete_done(struct tevent_req *subreq) { - return tldap_simple_done(subreq, TLDAP_RES_DELETE); + tldap_simple_done(subreq, TLDAP_RES_DELETE); } int tldap_delete_recv(struct tevent_req *req) -- cgit From 2fca950d68bff3641ed3ac4bdaee1d16f0cca88a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 20:58:11 +0200 Subject: s3:libsmb: we need to include "includes.h" as first header to let code build on all platforms This should fix the Tru64 build. metze --- source3/libsmb/libsmb_thread_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libsmb/libsmb_thread_posix.c b/source3/libsmb/libsmb_thread_posix.c index 411ffbdfbb..6519659c25 100644 --- a/source3/libsmb/libsmb_thread_posix.c +++ b/source3/libsmb/libsmb_thread_posix.c @@ -17,8 +17,8 @@ along with this program. If not, see . */ -#include #include "includes.h" +#include #include "libsmbclient.h" #include "libsmb_internal.h" -- cgit From 377a97579bc9b733c5a6363c71498e2ecf894f02 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 21:02:42 +0200 Subject: s3:smbd: try to fix a compiler warning on i386 : left shift count >= width of type metze --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index d1f2e7ff18..06536f9e21 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4105,7 +4105,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, I think this causes us to fail the IFSKIT BasicFileInformationTest. -tpot */ file_index = ((sbuf.st_ex_ino) & UINT32_MAX); /* FileIndexLow */ - file_index |= ((sbuf.st_ex_dev) & UINT32_MAX) << 32; /* FileIndexHigh */ + file_index |= ((uint64_t)((sbuf.st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */ switch (info_level) { case SMB_INFO_STANDARD: -- cgit From 48a07321479c14a6618bb21302d27fd9606efbdd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Jul 2009 13:59:11 -0700 Subject: Fix bug #6551 - win98 clients cannot connect after server upgrade to samba-3.4.0. The values of vuid and tid were not being correctly updated in the struct smb_request when passed to chain_reply inside sessionsetupX and tconX. Jeremy. --- source3/smbd/reply.c | 2 ++ source3/smbd/sesssetup.c | 1 + 2 files changed, 3 insertions(+) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 4d0a2b8c97..a6e35c7342 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -856,6 +856,7 @@ void reply_tcon_and_X(struct smb_request *req) END_PROFILE(SMBtconX); + req->tid = conn->cnum; chain_reply(req); return; } @@ -2076,6 +2077,7 @@ void reply_ulogoffX(struct smb_request *req) DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) ); END_PROFILE(SMBulogoffX); + req->vuid = UID_FIELD_INVALID; chain_reply(req); } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 3988105fa4..2d2e5141ee 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1807,6 +1807,7 @@ void reply_sesssetup_and_X(struct smb_request *req) SSVAL(req->outbuf,smb_uid,sess_vuid); SSVAL(req->inbuf,smb_uid,sess_vuid); + req->vuid = sess_vuid; if (!sconn->smb1.sessions.done_sesssetup) { sconn->smb1.sessions.max_send = -- cgit From d6c44a704e9a138dba8398f45e9af2601826f659 Mon Sep 17 00:00:00 2001 From: "Timur I. Bakeyev" Date: Sun, 12 Jul 2009 23:36:08 +0000 Subject: Add ad-schema/*.txt and utils to the installmisc.sh Install other useful scripts from the setup/ directory, not only provisioning ones. Also install setup/ad-schema/*.txt files to the SETUPDIR. These are necessary for 'provision' to work properly. --- source4/script/installmisc.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source4/script/installmisc.sh b/source4/script/installmisc.sh index 2bd34b119f..0666ae1ade 100755 --- a/source4/script/installmisc.sh +++ b/source4/script/installmisc.sh @@ -8,11 +8,15 @@ cd $SRCDIR || exit 1 echo "Installing setup templates" mkdir -p $SETUPDIR || exit 1 +mkdir -p $SETUPDIR/ad-schema || exit 1 +cp setup/ad-schema/*.txt $SETUPDIR/ad-schema || exit 1 +for p in enableaccount newuser provision provision-backend setexpiry setpassword +do + chmod 0555 setup/$p + cp setup/$p $SETUPDIR || exit 1 +done cp setup/schema-map-* $SETUPDIR || exit 1 cp setup/DB_CONFIG $SETUPDIR || exit 1 -cp setup/provision-backend $SETUPDIR || exit 1 -cp setup/provision $SETUPDIR || exit 1 -cp setup/newuser $SETUPDIR || exit 1 cp setup/*.inf $SETUPDIR || exit 1 cp setup/*.ldif $SETUPDIR || exit 1 cp setup/*.reg $SETUPDIR || exit 1 -- cgit From ba58edd0bc2d77c6ed1b6a76f33787da9031db5b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 14 Jul 2009 08:00:09 +1000 Subject: Add a way to set an opaque integer onto a samdb This will allow us to set some more flags into ldb during the provision. --- source4/scripting/python/pyglue.c | 59 +++++++++++++++++++++++++++++++++ source4/scripting/python/samba/samdb.py | 8 +++++ 2 files changed, 67 insertions(+) diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c index 5816d9637d..abd018f6fc 100644 --- a/source4/scripting/python/pyglue.c +++ b/source4/scripting/python/pyglue.c @@ -204,6 +204,63 @@ static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject *py_dsdb_set_opaque_integer(PyObject *self, PyObject *args) +{ + PyObject *py_ldb; + int value; + int *old_val, *new_val; + char *py_opaque_name, *opaque_name_talloc; + struct ldb_context *ldb; + TALLOC_CTX *tmp_ctx; + + if (!PyArg_ParseTuple(args, "Osi", &py_ldb, &py_opaque_name, &value)) + return NULL; + + PyErr_LDB_OR_RAISE(py_ldb, ldb); + + /* see if we have a cached copy */ + old_val = (int *)ldb_get_opaque(ldb, + py_opaque_name); + + if (old_val) { + *old_val = value; + Py_RETURN_NONE; + } + + tmp_ctx = talloc_new(ldb); + if (tmp_ctx == NULL) { + goto failed; + } + + new_val = talloc(tmp_ctx, int); + if (!new_val) { + goto failed; + } + + opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name); + if (!opaque_name_talloc) { + goto failed; + } + + *new_val = value; + + /* cache the domain_sid in the ldb */ + if (ldb_set_opaque(ldb, opaque_name_talloc, new_val) != LDB_SUCCESS) { + goto failed; + } + + talloc_steal(ldb, new_val); + talloc_steal(ldb, opaque_name_talloc); + talloc_free(tmp_ctx); + + Py_RETURN_NONE; + +failed: + talloc_free(tmp_ctx); + PyErr_SetString(PyExc_RuntimeError, "Failed to set opaque integer into the ldb!\n"); + return NULL; +} + static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args) { PyObject *py_ldb; @@ -284,6 +341,8 @@ static PyMethodDef py_misc_methods[] = { "Register Samba-specific LDB modules and schemas." }, { "dsdb_set_ntds_invocation_id", (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS, NULL }, + { "dsdb_set_opaque_integer", (PyCFunction)py_dsdb_set_opaque_integer, METH_VARARGS, + NULL }, { "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS, NULL }, { "dsdb_attach_schema_from_ldif", (PyCFunction)py_dsdb_attach_schema_from_ldif, METH_VARARGS, diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index bc76cd3c5f..6cb2469846 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -231,6 +231,14 @@ userPassword:: %s """ glue.dsdb_set_ntds_invocation_id(self, invocation_id) + def set_opaque_integer(self, name, value): + """Set an integer as an opaque (a flag or other value) value on the database + + :param name: The name for the opaque value + :param value: The integer value + """ + glue.dsdb_set_opaque_integer(self, name, value) + def setexpiry(self, user, expiry_seconds, noexpiry): """Set the account expiry for a user -- cgit From 271b5af92e9aada36adc648a6dd43a13c5aed340 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 14 Jul 2009 08:15:50 +1000 Subject: s4:dsdb Handle dc/domain/forest functional levels properly Rather than have the functional levels scattered in 4 different, unconnected locations, the provision script now sets it, and the rootdse module maintains it's copy only as a cached view onto the original values. We also use the functional level to determine if we should store AES Kerberos keys. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/password_hash.c | 7 +- source4/dsdb/samdb/ldb_modules/rootdse.c | 140 ++++++++++++++++++++++++- source4/scripting/python/pyglue.c | 6 ++ source4/scripting/python/samba/__init__.py | 5 + source4/scripting/python/samba/provision.py | 24 ++++- source4/setup/provision_basedn_modify.ldif | 4 +- source4/setup/provision_configuration.ldif | 2 +- source4/setup/provision_rootdse_add.ldif | 3 - source4/setup/provision_self_join.ldif | 4 +- 9 files changed, 174 insertions(+), 21 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index a28ca1d568..ef641ac18b 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -1026,6 +1026,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) uint8_t zero16[16]; bool do_newer_keys = false; bool do_cleartext = false; + int *domainFunctionality; ZERO_STRUCT(zero16); ZERO_STRUCT(names); @@ -1064,10 +1065,10 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) _old_scb.sub.signature, SUPPLEMENTAL_CREDENTIALS_SIGNATURE); } } + /* Per MS-SAMR 3.1.1.8.11.6 we create AES keys if our domain functionality level is 2008 or higher */ + domainFunctionality = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int); - /* TODO: do the correct check for this, it maybe depends on the functional level? */ - do_newer_keys = lp_parm_bool(ldb_get_opaque(ldb, "loadparm"), - NULL, "password_hash", "create_aes_key", false); + do_newer_keys = *domainFunctionality && (*domainFunctionality >= DS_BEHAVIOR_WIN2008); if (io->domain->store_cleartext && (io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) { diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 7080fb632f..59ea51dbce 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -59,6 +59,7 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms struct private_data *priv = talloc_get_type(ldb_module_get_private(module), struct private_data); char **server_sasl; const struct dsdb_schema *schema; + int *val; ldb = ldb_module_get_ctx(module); schema = dsdb_get_schema(ldb); @@ -77,7 +78,7 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms } } - if (do_attribute(attrs, "supportedControl")) { + if (priv && do_attribute(attrs, "supportedControl")) { int i; for (i = 0; i < priv->num_controls; i++) { char *control = talloc_strdup(msg, priv->controls[i]); @@ -91,7 +92,7 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms } } - if (do_attribute(attrs, "namingContexts")) { + if (priv && do_attribute(attrs, "namingContexts")) { int i; for (i = 0; i < priv->num_partitions; i++) { struct ldb_dn *dn = priv->partitions[i]; @@ -201,13 +202,37 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms } } - if (schema && do_attribute_explicit(attrs, "vendorVersion")) { + if (do_attribute_explicit(attrs, "vendorVersion")) { if (ldb_msg_add_fmt(msg, "vendorVersion", "%s", SAMBA_VERSION_STRING) != 0) { goto failed; } } + if (priv && do_attribute(attrs, "domainFunctionality") + && (val = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int))) { + if (ldb_msg_add_fmt(msg, "domainFunctionality", + "%d", *val) != 0) { + goto failed; + } + } + + if (priv && do_attribute(attrs, "forestFunctionality") + && (val = talloc_get_type(ldb_get_opaque(ldb, "forestFunctionality"), int))) { + if (ldb_msg_add_fmt(msg, "forestFunctionality", + "%d", *val) != 0) { + goto failed; + } + } + + if (priv && do_attribute(attrs, "domainControllerFunctionality") + && (val = talloc_get_type(ldb_get_opaque(ldb, "domainControllerFunctionality"), int))) { + if (ldb_msg_add_fmt(msg, "domainControllerFunctionality", + "%d", *val) != 0) { + goto failed; + } + } + /* TODO: lots more dynamic attributes should be added here */ return LDB_SUCCESS; @@ -394,12 +419,17 @@ static int rootdse_request(struct ldb_module *module, struct ldb_request *req) static int rootdse_init(struct ldb_module *module) { + int ret; struct ldb_context *ldb; + struct ldb_result *res; struct private_data *data; + const char *attrs[] = { "msDS-Behavior-Version", NULL }; + const char *ds_attrs[] = { "dsServiceName", NULL }; + TALLOC_CTX *mem_ctx; ldb = ldb_module_get_ctx(module); - data = talloc(module, struct private_data); + data = talloc_zero(module, struct private_data); if (data == NULL) { return -1; } @@ -412,7 +442,107 @@ static int rootdse_init(struct ldb_module *module) ldb_set_default_dns(ldb); - return ldb_next_init(module); + ret = ldb_next_init(module); + + if (ret) { + return ret; + } + + mem_ctx = talloc_new(data); + if (!mem_ctx) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Now that the partitions are set up, do a search for: + - domainControllerFunctionality + - domainFunctionality + - forestFunctionality + + Then stuff these values into an opaque + */ + ret = ldb_search(ldb, mem_ctx, &res, + ldb_get_default_basedn(ldb), + LDB_SCOPE_BASE, attrs, NULL); + if (ret == LDB_SUCCESS && res->count == 1) { + int domain_behaviour_version + = ldb_msg_find_attr_as_int(res->msgs[0], + "msDS-Behavior-Version", -1); + if (domain_behaviour_version != -1) { + int *val = talloc(ldb, int); + if (!val) { + ldb_oom(ldb); + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + *val = domain_behaviour_version; + ret = ldb_set_opaque(ldb, "domainFunctionality", val); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + return ret; + } + } + } + + ret = ldb_search(ldb, mem_ctx, &res, + samdb_partitions_dn(ldb, mem_ctx), + LDB_SCOPE_BASE, attrs, NULL); + if (ret == LDB_SUCCESS && res->count == 1) { + int forest_behaviour_version + = ldb_msg_find_attr_as_int(res->msgs[0], + "msDS-Behavior-Version", -1); + if (forest_behaviour_version != -1) { + int *val = talloc(ldb, int); + if (!val) { + ldb_oom(ldb); + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + *val = forest_behaviour_version; + ret = ldb_set_opaque(ldb, "forestFunctionality", val); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + return ret; + } + } + } + + ret = ldb_search(ldb, mem_ctx, &res, + ldb_dn_new(mem_ctx, ldb, ""), + LDB_SCOPE_BASE, ds_attrs, NULL); + if (ret == LDB_SUCCESS && res->count == 1) { + struct ldb_dn *ds_dn + = ldb_msg_find_attr_as_dn(ldb, mem_ctx, res->msgs[0], + "dsServiceName"); + if (ds_dn) { + ret = ldb_search(ldb, mem_ctx, &res, ds_dn, + LDB_SCOPE_BASE, attrs, NULL); + if (ret == LDB_SUCCESS && res->count == 1) { + int domain_controller_behaviour_version + = ldb_msg_find_attr_as_int(res->msgs[0], + "msDS-Behavior-Version", -1); + if (domain_controller_behaviour_version != -1) { + int *val = talloc(ldb, int); + if (!val) { + ldb_oom(ldb); + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + *val = domain_controller_behaviour_version; + ret = ldb_set_opaque(ldb, + "domainControllerFunctionality", val); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + return ret; + } + } + } + } + } + + talloc_free(mem_ctx); + + return LDB_SUCCESS; } static int rootdse_modify(struct ldb_module *module, struct ldb_request *req) diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c index abd018f6fc..c6b731ce8b 100644 --- a/source4/scripting/python/pyglue.c +++ b/source4/scripting/python/pyglue.c @@ -362,5 +362,11 @@ void initglue(void) return; PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING)); + + PyModule_AddObject(m, "DS_BEHAVIOR_WIN2000", PyInt_FromLong(DS_BEHAVIOR_WIN2000)); + PyModule_AddObject(m, "DS_BEHAVIOR_WIN2003_INTERIM", PyInt_FromLong(DS_BEHAVIOR_WIN2003_INTERIM)); + PyModule_AddObject(m, "DS_BEHAVIOR_WIN2003", PyInt_FromLong(DS_BEHAVIOR_WIN2003)); + PyModule_AddObject(m, "DS_BEHAVIOR_WIN2008", PyInt_FromLong(DS_BEHAVIOR_WIN2008)); + } diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 60a7919136..e3ebc4a637 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -242,3 +242,8 @@ def valid_netbios_name(name): return True version = glue.version + +DS_BEHAVIOR_WIN2000 = glue.DS_BEHAVIOR_WIN2000 +DS_BEHAVIOR_WIN2003_INTERIM = glue.DS_BEHAVIOR_WIN2003_INTERIM +DS_BEHAVIOR_WIN2003 = glue.DS_BEHAVIOR_WIN2003 +DS_BEHAVIOR_WIN2008 = glue.DS_BEHAVIOR_WIN2008 diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 189c93a1fc..8f57105224 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -37,7 +37,8 @@ import param import registry import samba from auth import system_session -from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted +from samba import version, Ldb, substitute_var, valid_netbios_name, check_all_substituted, \ + DS_BEHAVIOR_WIN2000, DS_BEHAVIOR_WIN2003_INTERIM, DS_BEHAVIOR_WIN2003, DS_BEHAVIOR_WIN2008 from samba.samdb import SamDB from samba.idmap import IDmapDB from samba.dcerpc import security @@ -729,7 +730,7 @@ def setup_samdb_rootdse(samdb, setup_path, names): def setup_self_join(samdb, names, machinepass, dnspass, domainsid, invocationid, setup_path, - policyguid): + policyguid, domainControllerFunctionality): """Join a host to its own domain.""" assert isinstance(invocationid, str) setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { @@ -745,7 +746,9 @@ def setup_self_join(samdb, names, "DNSPASS_B64": b64encode(dnspass), "REALM": names.realm, "DOMAIN": names.domain, - "DNSDOMAIN": names.dnsdomain}) + "DNSDOMAIN": names.dnsdomain, + "SAMBA_VERSION_STRING": version, + "DOMAIN_CONTROLLER_FUNCTIONALITY": str(domainControllerFunctionality)}) setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { "POLICYGUID": policyguid, "DNSDOMAIN": names.dnsdomain, @@ -765,6 +768,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, :note: This will wipe the main SAM database file! """ + domainFunctionality = DS_BEHAVIOR_WIN2008 + forestFunctionality = DS_BEHAVIOR_WIN2008 + domainControllerFunctionality = DS_BEHAVIOR_WIN2008 + erase = (fill != FILL_DRS) # Also wipes the database @@ -780,6 +787,11 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, return samdb message("Pre-loading the Samba 4 and AD schema") + + samdb.set_opaque_integer("domainFunctionality", domainFunctionality) + samdb.set_opaque_integer("forestFunctionality", forestFunctionality) + samdb.set_opaque_integer("domainControllerFunctionality", domainControllerFunctionality) + samdb.set_domain_sid(str(domainsid)) if serverrole == "domain controller": samdb.set_invocation_id(invocationid) @@ -818,6 +830,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "POLICYGUID": policyguid, "DOMAINDN": names.domaindn, "DOMAINGUID_MOD": domainguid_mod, + "DOMAIN_FUNCTIONALITY": str(domainFunctionality) }) message("Adding configuration container (permitted to fail)") @@ -864,7 +877,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "DOMAIN": names.domain, "SCHEMADN": names.schemadn, "DOMAINDN": names.domaindn, - "SERVERDN": names.serverdn + "SERVERDN": names.serverdn, + "FOREST_FUNCTIONALALITY": str(forestFunctionality) }) message("Setting up display specifiers") @@ -908,7 +922,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, dnspass=dnspass, machinepass=machinepass, domainsid=domainsid, policyguid=policyguid, - setup_path=setup_path) + setup_path=setup_path, domainControllerFunctionality=domainControllerFunctionality) except: samdb.transaction_cancel() diff --git a/source4/setup/provision_basedn_modify.ldif b/source4/setup/provision_basedn_modify.ldif index a7f3ce985c..36e80ec69c 100644 --- a/source4/setup/provision_basedn_modify.ldif +++ b/source4/setup/provision_basedn_modify.ldif @@ -47,10 +47,10 @@ replace: serverState serverState: 1 - replace: nTMixedDomain -nTMixedDomain: 1 +nTMixedDomain: 0 - replace: msDS-Behavior-Version -msDS-Behavior-Version: 0 +msDS-Behavior-Version: ${DOMAIN_FUNCTIONALITY} - replace: ridManagerReference ridManagerReference: CN=RID Manager$,CN=System,${DOMAINDN} diff --git a/source4/setup/provision_configuration.ldif b/source4/setup/provision_configuration.ldif index e84ac8517e..0dad24c705 100644 --- a/source4/setup/provision_configuration.ldif +++ b/source4/setup/provision_configuration.ldif @@ -6,7 +6,7 @@ objectClass: top objectClass: crossRefContainer cn: Partitions systemFlags: -2147483648 -msDS-Behavior-Version: 0 +msDS-Behavior-Version: ${FOREST_FUNCTIONALALITY} fSMORoleOwner: CN=NTDS Settings,${SERVERDN} dn: CN=Enterprise Configuration,CN=Partitions,${CONFIGDN} diff --git a/source4/setup/provision_rootdse_add.ldif b/source4/setup/provision_rootdse_add.ldif index e4e4309a90..f9ee4e5904 100644 --- a/source4/setup/provision_rootdse_add.ldif +++ b/source4/setup/provision_rootdse_add.ldif @@ -11,9 +11,6 @@ supportedLDAPVersion: 2 dnsHostName: ${DNSNAME} ldapServiceName: ${DNSDOMAIN}:${NETBIOSNAME}$@${REALM} serverName: ${SERVERDN} -domainFunctionality: 0 -forestFunctionality: 0 -domainControllerFunctionality: 2 isSynchronized: FALSE vendorName: Samba Team (http://samba.org) supportedCapabilities: 1.2.840.113556.1.4.800 diff --git a/source4/setup/provision_self_join.ldif b/source4/setup/provision_self_join.ldif index b7ca872319..b60fea6576 100644 --- a/source4/setup/provision_self_join.ldif +++ b/source4/setup/provision_self_join.ldif @@ -13,7 +13,7 @@ primaryGroupID: 516 accountExpires: 9223372036854775807 sAMAccountName: ${NETBIOSNAME}$ operatingSystem: Samba -operatingSystemVersion: 4.0 +operatingSystemVersion: ${SAMBA_VERSION_STRING} dNSHostName: ${DNSNAME} isCriticalSystemObject: TRUE userPassword:: ${MACHINEPASS_B64} @@ -57,7 +57,7 @@ options: 1 systemFlags: 33554432 dMDLocation: ${SCHEMADN} invocationId: ${INVOCATIONID} -msDS-Behavior-Version: 2 +msDS-Behavior-Version: ${DOMAIN_CONTROLLER_FUNCTIONALITY} msDS-hasMasterNCs: ${CONFIGDN} msDS-hasMasterNCs: ${SCHEMADN} msDS-hasMasterNCs: ${DOMAINDN} -- cgit From bc354fb1a6fd524629434c199e2ca260a8400bb4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 14 Jul 2009 10:19:16 +1000 Subject: s4:gensec Allow mutual auth to be turned off in 'fake_gssapi_krb5' This allows the older 'like Samba3' GENSEC krb5 implementation to work against Windows 2008. I'm using this to track down interop issues in this area. Andrew Bartlett --- source4/auth/gensec/gensec_krb5.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 09bdec512d..aed6822b89 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -57,6 +57,7 @@ struct gensec_krb5_state { krb5_keyblock *keyblock; krb5_ticket *ticket; bool gssapi; + krb5_flags ap_req_options; }; static int gensec_krb5_destroy(struct gensec_krb5_state *gensec_krb5_state) @@ -221,7 +222,6 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security NTSTATUS nt_status; struct ccache_container *ccache_container; const char *hostname; - krb5_flags ap_req_options = AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED; const char *principal; krb5_data in_data; @@ -247,6 +247,11 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data; gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START; + gensec_krb5_state->ap_req_options = AP_OPTS_USE_SUBKEY; + + if (gensec_setting_bool(gensec_security->settings, "gensec_krb5", "mutual", true)) { + gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED; + } principal = gensec_get_target_principal(gensec_security); @@ -274,7 +279,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security if (ret == 0) { ret = krb5_mk_req_exact(gensec_krb5_state->smb_krb5_context->krb5_context, &gensec_krb5_state->auth_context, - ap_req_options, + gensec_krb5_state->ap_req_options, target_principal, &in_data, ccache_container->ccache, &gensec_krb5_state->enc_ticket); @@ -284,7 +289,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security } else { ret = krb5_mk_req(gensec_krb5_state->smb_krb5_context->krb5_context, &gensec_krb5_state->auth_context, - ap_req_options, + gensec_krb5_state->ap_req_options, gensec_get_target_service(gensec_security), hostname, &in_data, ccache_container->ccache, @@ -392,8 +397,13 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, } else { *out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->enc_ticket.data, gensec_krb5_state->enc_ticket.length); } - gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH; - nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; + if (gensec_krb5_state->ap_req_options & AP_OPTS_MUTUAL_REQUIRED) { + gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH; + nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; + } else { + gensec_krb5_state->state_position = GENSEC_KRB5_DONE; + nt_status = NT_STATUS_OK; + } return nt_status; } -- cgit From 84dca625cab96f72123308d80a5aeed5fc42f0c5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 14 Jul 2009 13:22:38 +1000 Subject: s4:heimdal The implied GSS_C_MUTUAL_FLAG depends on AP_OPTS_MUTUAL_REQUIRED We had previously assumed it was unconditional. Samba3 didn't mind very much, but Samba4's samba3-like client did, and the behaviour differed to Win2008 behaviour. Andrew Bartlett --- source4/heimdal/lib/gssapi/krb5/accept_sec_context.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c index e0944852a7..8ead2bdf75 100644 --- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c @@ -522,7 +522,10 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, * Samba style get some flags (but not DCE-STYLE) */ ctx->flags = - GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; + GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; + if (ap_options & AP_OPTS_MUTUAL_REQUIRED) { + ctx->flags |= GSS_C_MUTUAL_FLAG; + } } } -- cgit From e16a2a1fa941511a8eeefd05b397dd934a77c9f6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 16 Jul 2009 08:29:43 +1000 Subject: s4:gensec Rework gensec_krb5 mutual authentication defaults When emulating Samba3 (which we do to ensure we don't break compatability), don't do mutual authentication by default, as it breaks the session key with AES and isn't what Samba3 does anyway. Andrew Bartlett --- source4/auth/gensec/gensec_krb5.c | 52 +++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index aed6822b89..f4ef36a24d 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -89,7 +89,7 @@ static int gensec_krb5_destroy(struct gensec_krb5_state *gensec_krb5_state) return 0; } -static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) +static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security, bool gssapi) { krb5_error_code ret; struct gensec_krb5_state *gensec_krb5_state; @@ -115,7 +115,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) gensec_krb5_state->keyblock = NULL; gensec_krb5_state->session_key = data_blob(NULL, 0); gensec_krb5_state->pac = data_blob(NULL, 0); - gensec_krb5_state->gssapi = false; + gensec_krb5_state->gssapi = gssapi; talloc_set_destructor(gensec_krb5_state, gensec_krb5_destroy); @@ -187,12 +187,12 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) return NT_STATUS_OK; } -static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security) +static NTSTATUS gensec_krb5_common_server_start(struct gensec_security *gensec_security, bool gssapi) { NTSTATUS nt_status; struct gensec_krb5_state *gensec_krb5_state; - nt_status = gensec_krb5_start(gensec_security); + nt_status = gensec_krb5_start(gensec_security, gssapi); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } @@ -203,19 +203,17 @@ static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security return NT_STATUS_OK; } -static NTSTATUS gensec_fake_gssapi_krb5_server_start(struct gensec_security *gensec_security) +static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security) { - NTSTATUS nt_status = gensec_krb5_server_start(gensec_security); + return gensec_krb5_common_server_start(gensec_security, false); +} - if (NT_STATUS_IS_OK(nt_status)) { - struct gensec_krb5_state *gensec_krb5_state; - gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data; - gensec_krb5_state->gssapi = true; - } - return nt_status; +static NTSTATUS gensec_fake_gssapi_krb5_server_start(struct gensec_security *gensec_security) +{ + return gensec_krb5_common_server_start(gensec_security, true); } -static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security) +static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_security, bool gssapi) { struct gensec_krb5_state *gensec_krb5_state; krb5_error_code ret; @@ -240,7 +238,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security return NT_STATUS_INVALID_PARAMETER; } - nt_status = gensec_krb5_start(gensec_security); + nt_status = gensec_krb5_start(gensec_security, gssapi); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } @@ -249,8 +247,16 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START; gensec_krb5_state->ap_req_options = AP_OPTS_USE_SUBKEY; - if (gensec_setting_bool(gensec_security->settings, "gensec_krb5", "mutual", true)) { - gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED; + if (gensec_krb5_state->gssapi) { + /* The Fake GSSAPI modal emulates Samba3, which does not do mutual authentication */ + if (gensec_setting_bool(gensec_security->settings, "gensec_fake_gssapi_krb5", "mutual", false)) { + gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED; + } + } else { + /* The wrapping for KPASSWD (a user of the raw KRB5 API) should be mutually authenticated */ + if (gensec_setting_bool(gensec_security->settings, "gensec_krb5", "mutual", true)) { + gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED; + } } principal = gensec_get_target_principal(gensec_security); @@ -333,16 +339,14 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security } } -static NTSTATUS gensec_fake_gssapi_krb5_client_start(struct gensec_security *gensec_security) +static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security) { - NTSTATUS nt_status = gensec_krb5_client_start(gensec_security); + return gensec_krb5_common_client_start(gensec_security, false); +} - if (NT_STATUS_IS_OK(nt_status)) { - struct gensec_krb5_state *gensec_krb5_state; - gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data; - gensec_krb5_state->gssapi = true; - } - return nt_status; +static NTSTATUS gensec_fake_gssapi_krb5_client_start(struct gensec_security *gensec_security) +{ + return gensec_krb5_common_client_start(gensec_security, true); } /** -- cgit From c3f461c35f9ca1b6a0e01efe53fbf439faaddad9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 3 Jul 2009 22:01:01 +0200 Subject: s4-smbtorture: some work on getprinterdriver and getprinterdriver2 tests. Guenther --- source4/torture/rpc/spoolss.c | 69 ++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index a515ef6baa..ddc14f33a2 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -2537,12 +2537,45 @@ static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pi return ret; } -#if 0 -static bool test_GetPrinterDriver2(struct dcerpc_pipe *p, +static bool test_GetPrinterDriver(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *handle, + const char *driver_name) +{ + struct spoolss_GetPrinterDriver r; + uint32_t needed; + + r.in.handle = handle; + r.in.architecture = "W32X86"; + r.in.level = 1; + r.in.buffer = NULL; + r.in.offered = 0; + r.out.needed = &needed; + + torture_comment(tctx, "Testing GetPrinterDriver level %d\n", r.in.level); + + torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver(p, tctx, &r), + "failed to call GetPrinterDriver"); + if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { + DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed); + data_blob_clear(&blob); + r.in.buffer = &blob; + r.in.offered = needed; + torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver(p, tctx, &r), + "failed to call GetPrinterDriver"); + } + + torture_assert_werr_ok(tctx, r.out.result, + "failed to call GetPrinterDriver"); + + return true; +} + +static bool test_GetPrinterDriver2(struct torture_context *tctx, + struct dcerpc_pipe *p, struct policy_handle *handle, const char *driver_name) { - NTSTATUS status; struct spoolss_GetPrinterDriver2 r; uint32_t needed; uint32_t server_major_version; @@ -2559,34 +2592,24 @@ static bool test_GetPrinterDriver2(struct dcerpc_pipe *p, r.out.server_major_version = &server_major_version; r.out.server_minor_version = &server_minor_version; - printf("Testing GetPrinterDriver2\n"); - - status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r); - if (!NT_STATUS_IS_OK(status)) { - printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status)); - return false; - } + torture_comment(tctx, "Testing GetPrinterDriver2 level %d\n", r.in.level); + torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r), + "failed to call GetPrinterDriver2"); if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { + DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed); + data_blob_clear(&blob); + r.in.buffer = &blob; r.in.offered = needed; - status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r); - } - - if (!NT_STATUS_IS_OK(status)) { - printf("GetPrinterDriver2 failed - %s\n", - nt_errstr(status)); - return false; + torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r), + "failed to call GetPrinterDriver2"); } - if (!W_ERROR_IS_OK(r.out.result)) { - printf("GetPrinterDriver2 failed - %s\n", - win_errstr(r.out.result)); - return false; - } + torture_assert_werr_ok(tctx, r.out.result, + "failed to call GetPrinterDriver2"); return true; } -#endif static bool test_EnumPrinterDrivers_old(struct torture_context *tctx, struct dcerpc_pipe *p) -- cgit From 33768fea073fb24763728c1da3424465ebabc1f0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 15 Jul 2009 21:59:05 +0200 Subject: s3-spoolss: make some of the command hooks static. Guenther --- source3/include/proto.h | 3 --- source3/rpc_server/srv_spoolss_nt.c | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 15e3f325aa..740cc4198b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5906,7 +5906,6 @@ void copy_id26_to_sam_passwd(struct samu *to, /* The following definitions come from rpc_server/srv_spoolss_nt.c */ -WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename ); void do_drv_upgrade_printer(struct messaging_context *msg, void *private_data, uint32_t msg_type, @@ -5995,9 +5994,7 @@ void construct_info_data(struct spoolss_Notify *info_data, int id); struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx, const char *servicename); -WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri ); bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer); -WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines ); /* The following definitions come from rpc_server/srv_srvsvc_nt.c */ diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 9d72168202..48ac103667 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -261,7 +261,7 @@ static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd) Delete a printer given a handle. ****************************************************************************/ -WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename ) +static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename) { char *cmd = lp_deleteprinter_cmd(); char *command = NULL; @@ -5920,7 +5920,7 @@ static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) /**************************************************************************** ****************************************************************************/ -WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri ) +static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri) { char *cmd = lp_addport_cmd(); char *command = NULL; @@ -7316,7 +7316,7 @@ static WERROR fill_port_2(TALLOC_CTX *mem_ctx, wrapper around the enumer ports command ****************************************************************************/ -WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines ) +static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines) { char *cmd = lp_enumports_cmd(); char **qlines = NULL; -- cgit From f982c912f47d5bfd00b4736573c7e4219a31a6c8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 15 Jul 2009 23:16:19 +0200 Subject: s3-rpc_parse: remove more unused code. Guenther --- source3/include/proto.h | 16 --- source3/rpc_parse/parse_prs.c | 318 ------------------------------------------ 2 files changed, 334 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 740cc4198b..d68aa4b619 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5676,32 +5676,16 @@ void prs_switch_type(prs_struct *ps, bool io); void prs_force_dynamic(prs_struct *ps); void prs_set_session_key(prs_struct *ps, const char sess_key[16]); bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8); -bool prs_pointer( const char *name, prs_struct *ps, int depth, - void *dta, size_t data_size, - bool (*prs_fn)(const char*, prs_struct*, int, void*) ); bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16); bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32); bool prs_int32(const char *name, prs_struct *ps, int depth, int32 *data32); bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64); -bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status); bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *status); -bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status); bool prs_uint8s(bool charmode, const char *name, prs_struct *ps, int depth, uint8 *data8s, int len); bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len); -bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len); bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len); bool prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str); bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size); -bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str); -bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset); -bool prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16, - uint32 ptr_uint16, uint32 start_offset); -bool prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset); -bool prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32, - uint32 ptr_uint32, uint32 data_size); -int tdb_prs_store(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps); -int tdb_prs_fetch(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps, TALLOC_CTX *mem_ctx); -bool prs_hash1(prs_struct *ps, uint32 offset, int len); void schannel_encode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level, enum schannel_direction direction, RPC_AUTH_SCHANNEL_CHK * verf, diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 0f4829dec3..621ccf4bc9 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -636,42 +636,6 @@ bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8) return True; } -/******************************************************************* - Stream a uint16* (allocate memory if unmarshalling) - ********************************************************************/ - -bool prs_pointer( const char *name, prs_struct *ps, int depth, - void *dta, size_t data_size, - bool (*prs_fn)(const char*, prs_struct*, int, void*) ) -{ - void ** data = (void **)dta; - uint32 data_p; - - /* output f000baaa to stream if the pointer is non-zero. */ - - data_p = *data ? 0xf000baaa : 0; - - if ( !prs_uint32("ptr", ps, depth, &data_p )) - return False; - - /* we're done if there is no data */ - - if ( !data_p ) - return True; - - if (UNMARSHALLING(ps)) { - if (data_size) { - if ( !(*data = PRS_ALLOC_MEM(ps, char, data_size)) ) - return False; - } else { - *data = NULL; - } - } - - return prs_fn(name, ps, depth, *data); -} - - /******************************************************************* Stream a uint16. ********************************************************************/ @@ -783,36 +747,6 @@ bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64) } } -/******************************************************************* - Stream a NTSTATUS - ********************************************************************/ - -bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status) -{ - char *q = prs_mem_get(ps, sizeof(uint32)); - if (q == NULL) - return False; - - if (UNMARSHALLING(ps)) { - if (ps->bigendian_data) - *status = NT_STATUS(RIVAL(q,0)); - else - *status = NT_STATUS(IVAL(q,0)); - } else { - if (ps->bigendian_data) - RSIVAL(q,0,NT_STATUS_V(*status)); - else - SIVAL(q,0,NT_STATUS_V(*status)); - } - - DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name, - nt_errstr(*status))); - - ps->data_offset += sizeof(uint32); - - return True; -} - /******************************************************************* Stream a DCE error code ********************************************************************/ @@ -843,38 +777,6 @@ bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *st return True; } - -/******************************************************************* - Stream a WERROR - ********************************************************************/ - -bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status) -{ - char *q = prs_mem_get(ps, sizeof(uint32)); - if (q == NULL) - return False; - - if (UNMARSHALLING(ps)) { - if (ps->bigendian_data) - *status = W_ERROR(RIVAL(q,0)); - else - *status = W_ERROR(IVAL(q,0)); - } else { - if (ps->bigendian_data) - RSIVAL(q,0,W_ERROR_V(*status)); - else - SIVAL(q,0,W_ERROR_V(*status)); - } - - DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name, - win_errstr(*status))); - - ps->data_offset += sizeof(uint32); - - return True; -} - - /****************************************************************** Stream an array of uint8s. Length is number of uint8s. ********************************************************************/ @@ -951,60 +853,6 @@ bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uin return True; } -/****************************************************************** - Start using a function for streaming unicode chars. If unmarshalling, - output must be little-endian, if marshalling, input must be little-endian. - ********************************************************************/ - -static void dbg_rw_punival(bool charmode, const char *name, int depth, prs_struct *ps, - char *in_buf, char *out_buf, int len) -{ - int i; - - if (UNMARSHALLING(ps)) { - if (ps->bigendian_data) { - for (i = 0; i < len; i++) - SSVAL(out_buf,2*i,RSVAL(in_buf, 2*i)); - } else { - for (i = 0; i < len; i++) - SSVAL(out_buf, 2*i, SVAL(in_buf, 2*i)); - } - } else { - if (ps->bigendian_data) { - for (i = 0; i < len; i++) - RSSVAL(in_buf, 2*i, SVAL(out_buf,2*i)); - } else { - for (i = 0; i < len; i++) - SSVAL(in_buf, 2*i, SVAL(out_buf,2*i)); - } - } - - DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth), ps->data_offset, name)); - if (charmode) - print_asc(5, (unsigned char*)out_buf, 2*len); - else { - for (i = 0; i < len; i++) - DEBUGADD(5,("%04x ", out_buf[i])); - } - DEBUGADD(5,("\n")); -} - -/****************************************************************** - Stream a unistr. Always little endian. - ********************************************************************/ - -bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len) -{ - char *q = prs_mem_get(ps, len * sizeof(uint16)); - if (q == NULL) - return False; - - dbg_rw_punival(charmode, name, depth, ps, q, (char *)data16s, len); - ps->data_offset += (len * sizeof(uint16)); - - return True; -} - /****************************************************************** Stream an array of uint32s. Length is number of uint32s. ********************************************************************/ @@ -1216,172 +1064,6 @@ bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_ return True; } -bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str) -{ - size_t len; - char *tmp_str; - - if (UNMARSHALLING(ps)) { - len = strlen(&ps->data_p[ps->data_offset]); - } else { - len = strlen(*str); - } - - tmp_str = PRS_ALLOC_MEM(ps, char, len+1); - - if (tmp_str == NULL) { - return False; - } - - if (MARSHALLING(ps)) { - strncpy(tmp_str, *str, len); - } - - if (!prs_string(name, ps, depth, tmp_str, len+1)) { - return False; - } - - *str = tmp_str; - return True; -} - -/******************************************************************* - prs_uint16 wrapper. Call this and it sets up a pointer to where the - uint16 should be stored, or gets the size if reading. - ********************************************************************/ - -bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset) -{ - *offset = ps->data_offset; - if (UNMARSHALLING(ps)) { - /* reading. */ - return prs_uint16(name, ps, depth, data16); - } else { - char *q = prs_mem_get(ps, sizeof(uint16)); - if(q ==NULL) - return False; - ps->data_offset += sizeof(uint16); - } - return True; -} - -/******************************************************************* - prs_uint16 wrapper. call this and it retrospectively stores the size. - does nothing on reading, as that is already handled by ...._pre() - ********************************************************************/ - -bool prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16, - uint32 ptr_uint16, uint32 start_offset) -{ - if (MARSHALLING(ps)) { - /* - * Writing - temporarily move the offset pointer. - */ - uint16 data_size = ps->data_offset - start_offset; - uint32 old_offset = ps->data_offset; - - ps->data_offset = ptr_uint16; - if(!prs_uint16(name, ps, depth, &data_size)) { - ps->data_offset = old_offset; - return False; - } - ps->data_offset = old_offset; - } else { - ps->data_offset = start_offset + (uint32)(*data16); - } - return True; -} - -/******************************************************************* - prs_uint32 wrapper. Call this and it sets up a pointer to where the - uint32 should be stored, or gets the size if reading. - ********************************************************************/ - -bool prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset) -{ - *offset = ps->data_offset; - if (UNMARSHALLING(ps) && (data32 != NULL)) { - /* reading. */ - return prs_uint32(name, ps, depth, data32); - } else { - ps->data_offset += sizeof(uint32); - } - return True; -} - -/******************************************************************* - prs_uint32 wrapper. call this and it retrospectively stores the size. - does nothing on reading, as that is already handled by ...._pre() - ********************************************************************/ - -bool prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32, - uint32 ptr_uint32, uint32 data_size) -{ - if (MARSHALLING(ps)) { - /* - * Writing - temporarily move the offset pointer. - */ - uint32 old_offset = ps->data_offset; - ps->data_offset = ptr_uint32; - if(!prs_uint32(name, ps, depth, &data_size)) { - ps->data_offset = old_offset; - return False; - } - ps->data_offset = old_offset; - } - return True; -} - -/* useful function to store a structure in rpc wire format */ -int tdb_prs_store(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps) -{ - TDB_DATA dbuf; - dbuf.dptr = (uint8 *)ps->data_p; - dbuf.dsize = prs_offset(ps); - return tdb_trans_store(tdb, kbuf, dbuf, TDB_REPLACE); -} - -/* useful function to fetch a structure into rpc wire format */ -int tdb_prs_fetch(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps, TALLOC_CTX *mem_ctx) -{ - TDB_DATA dbuf; - - prs_init_empty(ps, mem_ctx, UNMARSHALL); - - dbuf = tdb_fetch(tdb, kbuf); - if (!dbuf.dptr) - return -1; - - prs_give_memory(ps, (char *)dbuf.dptr, dbuf.dsize, True); - - return 0; -} - -/******************************************************************* - hash a stream. - ********************************************************************/ - -bool prs_hash1(prs_struct *ps, uint32 offset, int len) -{ - char *q; - - q = ps->data_p; - q = &q[offset]; - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("prs_hash1\n")); - dump_data(100, (uint8 *)ps->sess_key, 16); - dump_data(100, (uint8 *)q, len); -#endif - arcfour_crypt((uchar *) q, (const unsigned char *)ps->sess_key, len); - -#ifdef DEBUG_PASSWORD - dump_data(100, (uint8 *)q, len); -#endif - - return True; -} - /******************************************************************* Create a digest over the entire packet (including the data), and MD5 it with the session key. -- cgit From 2260cdbb53e1bcc64adf1910c8986a02e3697a36 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 02:08:17 +0200 Subject: s3-ldapsam: bring Fedora DS LDAP schema in line with OpenLDAP schema. Guenther --- examples/LDAP/samba-schema-FDS.ldif | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/LDAP/samba-schema-FDS.ldif b/examples/LDAP/samba-schema-FDS.ldif index e88559fc8a..fb16486374 100644 --- a/examples/LDAP/samba-schema-FDS.ldif +++ b/examples/LDAP/samba-schema-FDS.ldif @@ -115,6 +115,10 @@ attributeTypes: ( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold' DESC 'Loc attributeTypes: ( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff' DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # "refuse machine password change" attributeTypes: ( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange' DESC 'Allow Machine Password changes (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +# +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.68 NAME 'sambaClearTextPassword' DESC 'Clear text password (used for trusted domain passwords)' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) +# +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.69 NAME 'sambaPreviousClearTextPassword' DESC 'Previous clear text password (used for trusted domain passwords)' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) ## ####################################################################### ## objectClasses: used by Samba 3.0 schema ## @@ -154,3 +158,7 @@ objectClasses: ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCT ## DESC 'Samba Privilege' ## MUST ( sambaSID ) ## MAY ( sambaPrivilegeList ) ) +## +## Trusted Domain Relationships +## +objectClasses: ( 1.3.6.1.4.1.7165.2.2.15 NAME 'sambaTrustedDomainPassword' SUP top STRUCTURAL DESC 'Samba Trusted Domain Password' MUST ( sambaDomainName $ sambaSID $ sambaClearTextPassword $ sambaPwdLastSet ) MAY ( sambaPreviousClearTextPassword ) ) -- cgit From 05bec77e00cc0f974d8521f781dce9dcff897f76 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 02:48:34 +0200 Subject: lsa: fix typo in lsa_TrustDomInfoEnum enum in IDL. Guenther --- librpc/gen_ndr/lsa.h | 6 +++--- librpc/gen_ndr/ndr_lsa.c | 12 ++++++------ librpc/idl/lsa.idl | 4 ++-- source4/rpc_server/lsa/dcesrv_lsa.c | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/librpc/gen_ndr/lsa.h b/librpc/gen_ndr/lsa.h index 3c9a5d80a6..06fa44577e 100644 --- a/librpc/gen_ndr/lsa.h +++ b/librpc/gen_ndr/lsa.h @@ -445,7 +445,7 @@ enum lsa_TrustDomInfoEnum LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL=10, LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL=11, LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL=12, - LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES=13 + LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES=13 } #else { __donnot_use_enum_lsa_TrustDomInfoEnum=0x7FFFFFFF} @@ -461,7 +461,7 @@ enum lsa_TrustDomInfoEnum #define LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL ( 10 ) #define LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL ( 11 ) #define LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL ( 12 ) -#define LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES ( 13 ) +#define LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES ( 13 ) #endif ; @@ -603,7 +603,7 @@ union lsa_TrustedDomainInfo { struct lsa_TrustDomainInfoFullInfoInternal full_info_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL)] */ struct lsa_TrustDomainInfoInfoEx2Internal info_ex2_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL)] */ struct lsa_TrustDomainInfoFullInfo2Internal full_info2_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL)] */ - struct lsa_TrustDomainInfoSupportedEncTypes enc_types;/* [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES)] */ + struct lsa_TrustDomainInfoSupportedEncTypes enc_types;/* [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES)] */ }/* [switch_type(lsa_TrustDomInfoEnum)] */; struct lsa_DATA_BUF_PTR { diff --git a/librpc/gen_ndr/ndr_lsa.c b/librpc/gen_ndr/ndr_lsa.c index 3ad9c41fd7..2b12bbff90 100644 --- a/librpc/gen_ndr/ndr_lsa.c +++ b/librpc/gen_ndr/ndr_lsa.c @@ -2735,7 +2735,7 @@ _PUBLIC_ void ndr_print_lsa_TrustDomInfoEnum(struct ndr_print *ndr, const char * case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL"; break; case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL"; break; case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL"; break; - case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: val = "LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES"; break; + case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: val = "LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES"; break; } ndr_print_enum(ndr, name, "ENUM", val, r); } @@ -3662,7 +3662,7 @@ static enum ndr_err_code ndr_push_lsa_TrustedDomainInfo(struct ndr_push *ndr, in NDR_CHECK(ndr_push_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_SCALARS, &r->full_info2_internal)); break; } - case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: { + case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: { NDR_CHECK(ndr_push_lsa_TrustDomainInfoSupportedEncTypes(ndr, NDR_SCALARS, &r->enc_types)); break; } @@ -3720,7 +3720,7 @@ static enum ndr_err_code ndr_push_lsa_TrustedDomainInfo(struct ndr_push *ndr, in NDR_CHECK(ndr_push_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_BUFFERS, &r->full_info2_internal)); break; - case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: + case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: break; default: @@ -3789,7 +3789,7 @@ static enum ndr_err_code ndr_pull_lsa_TrustedDomainInfo(struct ndr_pull *ndr, in NDR_CHECK(ndr_pull_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_SCALARS, &r->full_info2_internal)); break; } - case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: { + case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: { NDR_CHECK(ndr_pull_lsa_TrustDomainInfoSupportedEncTypes(ndr, NDR_SCALARS, &r->enc_types)); break; } @@ -3846,7 +3846,7 @@ static enum ndr_err_code ndr_pull_lsa_TrustedDomainInfo(struct ndr_pull *ndr, in NDR_CHECK(ndr_pull_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_BUFFERS, &r->full_info2_internal)); break; - case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: + case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: break; default: @@ -3910,7 +3910,7 @@ _PUBLIC_ void ndr_print_lsa_TrustedDomainInfo(struct ndr_print *ndr, const char ndr_print_lsa_TrustDomainInfoFullInfo2Internal(ndr, "full_info2_internal", &r->full_info2_internal); break; - case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: + case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: ndr_print_lsa_TrustDomainInfoSupportedEncTypes(ndr, "enc_types", &r->enc_types); break; diff --git a/librpc/idl/lsa.idl b/librpc/idl/lsa.idl index 9e3b7d6048..3d7077ccac 100644 --- a/librpc/idl/lsa.idl +++ b/librpc/idl/lsa.idl @@ -651,7 +651,7 @@ import "misc.idl", "security.idl"; LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL = 10, LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL = 11, LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL = 12, - LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES = 13 + LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES = 13 } lsa_TrustDomInfoEnum; typedef [public,bitmap32bit] bitmap { @@ -788,7 +788,7 @@ import "misc.idl", "security.idl"; lsa_TrustDomainInfoInfoEx2Internal info_ex2_internal; [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL)] lsa_TrustDomainInfoFullInfo2Internal full_info2_internal; - [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES)] + [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES)] lsa_TrustDomainInfoSupportedEncTypes enc_types; } lsa_TrustedDomainInfo; diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index cbadf654fb..2b4a891556 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -1378,7 +1378,7 @@ static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_ = samdb_result_uint(msg, "posixOffset", 0); return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex); - case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: + case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: info->enc_types.enc_types = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5); break; -- cgit From e25325539a86912ce620875ef07beff5bcde6060 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 16 Jul 2009 09:53:14 +1000 Subject: s4:heimdal: import lorikeet-heimdal-200907152325 (commit 2bef9cd5378c01e9c2a74d6221761883bd11a5c5) --- source4/heimdal/kdc/kaserver.c | 16 +- source4/heimdal/kdc/kerberos5.c | 24 +- source4/heimdal/kdc/krb5tgs.c | 44 +- source4/heimdal/lib/gssapi/gssapi/gssapi.h | 61 +- source4/heimdal/lib/gssapi/krb5/8003.c | 2 - .../heimdal/lib/gssapi/krb5/accept_sec_context.c | 13 +- source4/heimdal/lib/gssapi/krb5/acquire_cred.c | 2 - source4/heimdal/lib/gssapi/krb5/add_cred.c | 2 - source4/heimdal/lib/gssapi/krb5/aeap.c | 219 +----- source4/heimdal/lib/gssapi/krb5/arcfour.c | 2 - .../heimdal/lib/gssapi/krb5/canonicalize_name.c | 2 - source4/heimdal/lib/gssapi/krb5/cfx.c | 773 ++++++++++++++++++++- source4/heimdal/lib/gssapi/krb5/compare_name.c | 2 - source4/heimdal/lib/gssapi/krb5/compat.c | 3 - source4/heimdal/lib/gssapi/krb5/context_time.c | 2 - source4/heimdal/lib/gssapi/krb5/copy_ccache.c | 2 - source4/heimdal/lib/gssapi/krb5/decapsulate.c | 2 - .../heimdal/lib/gssapi/krb5/delete_sec_context.c | 2 - source4/heimdal/lib/gssapi/krb5/display_name.c | 2 - source4/heimdal/lib/gssapi/krb5/display_status.c | 2 - source4/heimdal/lib/gssapi/krb5/duplicate_name.c | 2 - source4/heimdal/lib/gssapi/krb5/encapsulate.c | 2 - source4/heimdal/lib/gssapi/krb5/export_name.c | 2 - .../heimdal/lib/gssapi/krb5/export_sec_context.c | 2 - source4/heimdal/lib/gssapi/krb5/external.c | 2 - source4/heimdal/lib/gssapi/krb5/get_mic.c | 2 - source4/heimdal/lib/gssapi/krb5/import_name.c | 2 - .../heimdal/lib/gssapi/krb5/import_sec_context.c | 2 - source4/heimdal/lib/gssapi/krb5/indicate_mechs.c | 2 - source4/heimdal/lib/gssapi/krb5/init.c | 2 - source4/heimdal/lib/gssapi/krb5/init_sec_context.c | 4 +- source4/heimdal/lib/gssapi/krb5/inquire_context.c | 2 - source4/heimdal/lib/gssapi/krb5/inquire_cred.c | 2 - .../heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c | 2 - .../heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c | 2 - .../lib/gssapi/krb5/inquire_mechs_for_name.c | 2 - .../lib/gssapi/krb5/inquire_names_for_mech.c | 3 - .../lib/gssapi/krb5/inquire_sec_context_by_oid.c | 2 - source4/heimdal/lib/gssapi/krb5/prf.c | 2 - .../lib/gssapi/krb5/process_context_token.c | 2 - source4/heimdal/lib/gssapi/krb5/release_buffer.c | 2 - source4/heimdal/lib/gssapi/krb5/release_cred.c | 2 - source4/heimdal/lib/gssapi/krb5/release_name.c | 2 - source4/heimdal/lib/gssapi/krb5/sequence.c | 2 - source4/heimdal/lib/gssapi/krb5/set_cred_option.c | 2 - .../lib/gssapi/krb5/set_sec_context_option.c | 2 - source4/heimdal/lib/gssapi/krb5/unwrap.c | 2 - source4/heimdal/lib/gssapi/krb5/verify_mic.c | 2 - source4/heimdal/lib/gssapi/krb5/wrap.c | 4 +- source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c | 2 +- source4/heimdal/lib/gssapi/mech/gss_aeap.c | 58 +- .../heimdal/lib/gssapi/spnego/accept_sec_context.c | 66 +- source4/heimdal/lib/hdb/db.c | 3 +- source4/heimdal/lib/hdb/dbinfo.c | 2 - source4/heimdal/lib/hdb/ext.c | 2 - source4/heimdal/lib/hdb/hdb.asn1 | 4 +- source4/heimdal/lib/hdb/hdb.c | 1 - source4/heimdal/lib/hdb/hdb.h | 36 + source4/heimdal/lib/hdb/keys.c | 2 - source4/heimdal/lib/hdb/keytab.c | 87 +-- source4/heimdal/lib/hdb/mkey.c | 2 - source4/heimdal/lib/hdb/ndbm.c | 3 +- source4/heimdal/lib/hx509/crypto.c | 4 - source4/heimdal/lib/krb5/crypto.c | 277 +++++--- source4/heimdal/lib/krb5/get_addrs.c | 2 - source4/heimdal/lib/krb5/init_creds_pw.c | 2 +- source4/heimdal/lib/krb5/store_emem.c | 7 +- 67 files changed, 1210 insertions(+), 590 deletions(-) diff --git a/source4/heimdal/kdc/kaserver.c b/source4/heimdal/kdc/kaserver.c index 3702ab9281..69b5bb1d6e 100644 --- a/source4/heimdal/kdc/kaserver.c +++ b/source4/heimdal/kdc/kaserver.c @@ -493,10 +493,10 @@ do_authenticate (krb5_context context, goto out; } - ret = _kdc_check_flags (context, config, - client_entry, client_name, - server_entry, server_name, - TRUE); + ret = kdc_check_flags (context, config, + client_entry, client_name, + server_entry, server_name, + TRUE); if (ret) { make_error_reply (hdr, KAPWEXPIRED, reply); goto out; @@ -790,10 +790,10 @@ do_getticket (krb5_context context, goto out; } - ret = _kdc_check_flags (context, config, - client_entry, client_name, - server_entry, server_name, - FALSE); + ret = kdc_check_flags (context, config, + client_entry, client_name, + server_entry, server_name, + FALSE); if (ret) { make_error_reply (hdr, KAPWEXPIRED, reply); goto out; diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index e364dcc1d1..43d54bf702 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -678,6 +678,12 @@ kdc_check_flags(krb5_context context, hdb_entry *client = &client_ex->entry; /* check client */ + if (client->flags.locked_out) { + kdc_log(context, config, 0, + "Client (%s) is locked out", client_name); + return KRB5KDC_ERR_POLICY; + } + if (client->flags.invalid) { kdc_log(context, config, 0, "Client (%s) has invalid bit set", client_name); @@ -727,6 +733,11 @@ kdc_check_flags(krb5_context context, if (server_ex != NULL) { hdb_entry *server = &server_ex->entry; + if (server->flags.locked_out) { + kdc_log(context, config, 0, + "Client server locked out -- %s", server_name); + return KRB5KDC_ERR_POLICY; + } if (server->flags.invalid) { kdc_log(context, config, 0, "Server has invalid flag set -- %s", server_name); @@ -883,6 +894,7 @@ _kdc_as_rep(krb5_context context, AS_REP rep; KDCOptions f = b->kdc_options; hdb_entry_ex *client = NULL, *server = NULL; + HDB *clientdb; krb5_enctype cetype, setype, sessionetype; krb5_data e_data; EncTicketPart et; @@ -966,7 +978,7 @@ _kdc_as_rep(krb5_context context, */ ret = _kdc_db_fetch(context, config, client_princ, - HDB_F_GET_CLIENT | flags, NULL, &client); + HDB_F_GET_CLIENT | flags, &clientdb, &client); if(ret){ kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name, krb5_get_err_text(context, ret)); @@ -1114,8 +1126,8 @@ _kdc_as_rep(krb5_context context, "No client key matching pa-data (%s) -- %s", estr, client_name); free(estr); - free_EncryptedData(&enc_data); + continue; } @@ -1159,6 +1171,10 @@ _kdc_as_rep(krb5_context context, e_text = "Failed to decrypt PA-DATA"; free_EncryptedData(&enc_data); + + if (clientdb->hdb_auth_status) + (clientdb->hdb_auth_status)(context, clientdb, client, HDB_AUTH_WRONG_PASSWORD); + ret = KRB5KDC_ERR_PREAUTH_FAILED; continue; } @@ -1323,6 +1339,10 @@ _kdc_as_rep(krb5_context context, goto out; } + if (clientdb->hdb_auth_status) + (clientdb->hdb_auth_status)(context, clientdb, client, + HDB_AUTH_SUCCESS); + /* * Verify flags after the user been required to prove its identity * with in a preauth mech. diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index 59104da3d6..6b98506e81 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -492,6 +492,7 @@ check_tgs_flags(krb5_context context, static krb5_error_code check_constrained_delegation(krb5_context context, krb5_kdc_configuration *config, + HDB *clientdb, hdb_entry_ex *client, krb5_const_principal server) { @@ -499,21 +500,32 @@ check_constrained_delegation(krb5_context context, krb5_error_code ret; int i; - ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl); - if (ret) { - krb5_clear_error_message(context); - return ret; - } + /* if client delegates to itself, that ok */ + if (krb5_principal_compare(context, client->entry.principal, server) == TRUE) + return 0; - if (acl) { - for (i = 0; i < acl->len; i++) { - if (krb5_principal_compare(context, server, &acl->val[i]) == TRUE) - return 0; + if (clientdb->hdb_check_constrained_delegation) { + ret = clientdb->hdb_check_constrained_delegation(context, clientdb, client, server); + if (ret == 0) + return 0; + } else { + ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl); + if (ret) { + krb5_clear_error_message(context); + return ret; + } + + if (acl) { + for (i = 0; i < acl->len; i++) { + if (krb5_principal_compare(context, server, &acl->val[i]) == TRUE) + return 0; + } } + ret = KRB5KDC_ERR_BADOPTION; } kdc_log(context, config, 0, "Bad request for constrained delegation"); - return KRB5KDC_ERR_BADOPTION; + return ret; } /* @@ -1369,6 +1381,7 @@ tgs_build_reply(krb5_context context, krb5_principal client_principal = NULL; char *spn = NULL, *cpn = NULL; hdb_entry_ex *server = NULL, *client = NULL; + HDB *clientdb; krb5_realm ref_realm = NULL; EncTicketPart *tgt = &ticket->ticket; krb5_principals spp = NULL; @@ -1531,7 +1544,7 @@ server_lookup: } ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | HDB_F_CANON, - NULL, &client); + &clientdb, &client); if(ret) { const char *krbtgt_realm; @@ -1792,7 +1805,7 @@ server_lookup: if (ret) { kdc_log(context, config, 0, "failed to decrypt ticket for " - "constrained delegation from %s to %s ", spn, cpn); + "constrained delegation from %s to %s ", cpn, spn); goto out; } @@ -1800,16 +1813,17 @@ server_lookup: if (adtkt.flags.forwardable == 0) { kdc_log(context, config, 0, "Missing forwardable flag on ticket for " - "constrained delegation from %s to %s ", spn, cpn); + "constrained delegation from %s to %s ", cpn, spn); ret = KRB5KDC_ERR_BADOPTION; goto out; } - ret = check_constrained_delegation(context, config, client, sp); + ret = check_constrained_delegation(context, config, clientdb, + client, sp); if (ret) { kdc_log(context, config, 0, "constrained delegation from %s to %s not allowed", - spn, cpn); + cpn, spn); goto out; } diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h index 9fe2bb8b46..07c4b36325 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -768,42 +768,6 @@ gss_pseudo_random gss_buffer_t prf_out ); -/* - * AEAD support - */ - -OM_uint32 GSSAPI_LIB_FUNCTION -gss_wrap_iov(OM_uint32 * /* minor_status */, - gss_ctx_id_t /* context_handle */, - int /* conf_req_flag */, - gss_qop_t /* qop_req */, - int * /* conf_state */, - gss_iov_buffer_desc * /*iov */, - int /* iov_count */); - -OM_uint32 GSSAPI_LIB_FUNCTION -gss_unwrap_iov(OM_uint32 * /* minor_status */, - gss_ctx_id_t /* context_handle */, - int * /* conf_state */, - gss_qop_t * /* qop_state */, - gss_iov_buffer_desc * /* iov */, - int /* iov_count */); - -OM_uint32 GSSAPI_LIB_FUNCTION -gss_wrap_iov_length(OM_uint32 * /* minor_status */, - gss_ctx_id_t /* context_handle */, - int /* conf_req_flag */, - gss_qop_t /* qop_req */, - int * /* conf_state */, - gss_iov_buffer_desc * /* iov */, - int /* iov_count */); - -OM_uint32 GSSAPI_LIB_FUNCTION -gss_release_iov_buffer(OM_uint32 * /* minor_status */, - gss_iov_buffer_desc * /* iov */, - int /* iov_count */); - - OM_uint32 gss_store_cred(OM_uint32 * /* minor_status */, gss_cred_id_t /* input_cred_handle */, @@ -899,6 +863,31 @@ gss_decapsulate_token(gss_buffer_t /* input_token */, +/* + * AEAD support + */ + +/* + * GSS_IOV + */ + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_wrap_iov(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *, + gss_iov_buffer_desc *, int); + + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_unwrap_iov(OM_uint32 *, gss_ctx_id_t, int *, gss_qop_t *, + gss_iov_buffer_desc *, int); + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_wrap_iov_length(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *, + gss_iov_buffer_desc *, int); + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_release_iov_buffer(OM_uint32 *, gss_iov_buffer_desc *, int); + + #ifdef __cplusplus } #endif diff --git a/source4/heimdal/lib/gssapi/krb5/8003.c b/source4/heimdal/lib/gssapi/krb5/8003.c index f5181cc311..a6f0165e72 100644 --- a/source4/heimdal/lib/gssapi/krb5/8003.c +++ b/source4/heimdal/lib/gssapi/krb5/8003.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - krb5_error_code _gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p) { diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c index 8ead2bdf75..8d998ed098 100644 --- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER; krb5_keytab _gsskrb5_keytab; @@ -519,13 +517,12 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, } /* - * Samba style get some flags (but not DCE-STYLE) + * Samba style get some flags (but not DCE-STYLE), use + * ap_options to guess the mutual flag. */ - ctx->flags = - GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; - if (ap_options & AP_OPTS_MUTUAL_REQUIRED) { - ctx->flags |= GSS_C_MUTUAL_FLAG; - } + ctx->flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; + if (ap_options & AP_OPTS_MUTUAL_REQUIRED) + ctx->flags |= GSS_C_MUTUAL_FLAG; } } diff --git a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c index bfab5667be..4f6f38e674 100644 --- a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 __gsskrb5_ccache_lifetime(OM_uint32 *minor_status, krb5_context context, diff --git a/source4/heimdal/lib/gssapi/krb5/add_cred.c b/source4/heimdal/lib/gssapi/krb5/add_cred.c index aa96a45e45..adc8a09fa4 100644 --- a/source4/heimdal/lib/gssapi/krb5/add_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/add_cred.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_add_cred ( OM_uint32 *minor_status, const gss_cred_id_t input_cred_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c index 7dab7877d7..38a5ac2dbe 100644 --- a/source4/heimdal/lib/gssapi/krb5/aeap.c +++ b/source4/heimdal/lib/gssapi/krb5/aeap.c @@ -35,66 +35,6 @@ #include -static OM_uint32 -iov_allocate(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count) -{ - unsigned int i; - - for (i = 0; i < iov_count; i++) { - if (GSS_IOV_BUFFER_FLAGS(iov[i].type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE){ - void *ptr = malloc(iov[i].buffer.length); - if (ptr == NULL) - abort(); - if (iov[i].buffer.value) - memcpy(ptr, iov[i].buffer.value, iov[i].buffer.length); - iov[i].buffer.value = ptr; - iov[i].type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED; - } - } - return GSS_S_COMPLETE; -} - -static OM_uint32 -iov_map(OM_uint32 *minor_status, - const gss_iov_buffer_desc *iov, - int iov_count, - krb5_crypto_iov *data) -{ - unsigned int i; - - for (i = 0; i < iov_count; i++) { - switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) { - case GSS_IOV_BUFFER_TYPE_EMPTY: - data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; - break; - case GSS_IOV_BUFFER_TYPE_DATA: - data[i].flags = KRB5_CRYPTO_TYPE_DATA; - break; - case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: - data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; - break; - case GSS_IOV_BUFFER_TYPE_HEADER: - data[i].flags = KRB5_CRYPTO_TYPE_HEADER; - break; - case GSS_IOV_BUFFER_TYPE_TRAILER: - data[i].flags = KRB5_CRYPTO_TYPE_TRAILER; - break; - case GSS_IOV_BUFFER_TYPE_PADDING: - data[i].flags = KRB5_CRYPTO_TYPE_PADDING; - break; - case GSS_IOV_BUFFER_TYPE_STREAM: - abort(); - break; - default: - *minor_status = EINVAL; - return GSS_S_FAILURE; - } - data[i].data.data = iov[i].buffer.value; - data[i].data.length = iov[i].buffer.length; - } - return GSS_S_COMPLETE; -} - OM_uint32 GSSAPI_LIB_FUNCTION _gk_wrap_iov(OM_uint32 * minor_status, gss_ctx_id_t context_handle, @@ -104,50 +44,17 @@ _gk_wrap_iov(OM_uint32 * minor_status, gss_iov_buffer_desc *iov, int iov_count) { - gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; - krb5_context context; - OM_uint32 major_status, junk; - krb5_crypto_iov *data; - krb5_error_code ret; - unsigned usage; - - GSSAPI_KRB5_INIT (&context); - - major_status = iov_allocate(minor_status, iov, iov_count); - if (major_status != GSS_S_COMPLETE) - return major_status; - - data = calloc(iov_count, sizeof(data[0])); - if (data == NULL) { - gss_release_iov_buffer(&junk, iov, iov_count); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - major_status = iov_map(minor_status, iov, iov_count, data); - if (major_status != GSS_S_COMPLETE) { - gss_release_iov_buffer(&junk, iov, iov_count); - free(data); - return major_status; - } + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; + krb5_context context; - if (ctx->more_flags & LOCAL) { - usage = KRB5_KU_USAGE_ACCEPTOR_SIGN; - } else { - usage = KRB5_KU_USAGE_INITIATOR_SIGN; - } + GSSAPI_KRB5_INIT (&context); - ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage, - data, iov_count, NULL); - free(data); - if (ret) { - gss_release_iov_buffer(&junk, iov, iov_count); - *minor_status = ret; - return GSS_S_FAILURE; - } + if (ctx->more_flags & IS_CFX) + return _gssapi_wrap_cfx_iov(minor_status, ctx, context, + conf_req_flag, conf_state, + iov, iov_count); - *minor_status = 0; - return GSS_S_COMPLETE; + return GSS_S_FAILURE; } OM_uint32 GSSAPI_LIB_FUNCTION @@ -158,50 +65,16 @@ _gk_unwrap_iov(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count) { - gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; krb5_context context; - krb5_error_code ret; - OM_uint32 major_status, junk; - krb5_crypto_iov *data; - unsigned usage; GSSAPI_KRB5_INIT (&context); - - major_status = iov_allocate(minor_status, iov, iov_count); - if (major_status != GSS_S_COMPLETE) - return major_status; - - data = calloc(iov_count, sizeof(data[0])); - if (data == NULL) { - gss_release_iov_buffer(&junk, iov, iov_count); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - major_status = iov_map(minor_status, iov, iov_count, data); - if (major_status != GSS_S_COMPLETE) { - gss_release_iov_buffer(&junk, iov, iov_count); - free(data); - return major_status; - } - - if (ctx->more_flags & LOCAL) { - usage = KRB5_KU_USAGE_INITIATOR_SIGN; - } else { - usage = KRB5_KU_USAGE_ACCEPTOR_SIGN; - } - - ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage, - data, iov_count, NULL); - free(data); - if (ret) { - *minor_status = ret; - gss_release_iov_buffer(&junk, iov, iov_count); - return GSS_S_FAILURE; - } - - *minor_status = 0; - return GSS_S_COMPLETE; + + if (ctx->more_flags & IS_CFX) + return _gssapi_unwrap_cfx_iov(minor_status, ctx, context, + conf_state, qop_state, iov, iov_count); + + return GSS_S_FAILURE; } OM_uint32 GSSAPI_LIB_FUNCTION @@ -213,59 +86,15 @@ _gk_wrap_iov_length(OM_uint32 * minor_status, gss_iov_buffer_desc *iov, int iov_count) { - gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; krb5_context context; - unsigned int i; - size_t size; - size_t *padding = NULL; - + GSSAPI_KRB5_INIT (&context); - *minor_status = 0; - - for (size = 0, i = 0; i < iov_count; i++) { - switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) { - case GSS_IOV_BUFFER_TYPE_EMPTY: - break; - case GSS_IOV_BUFFER_TYPE_DATA: - size += iov[i].buffer.length; - break; - case GSS_IOV_BUFFER_TYPE_HEADER: - iov[i].buffer.length = - krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER); - size += iov[i].buffer.length; - break; - case GSS_IOV_BUFFER_TYPE_TRAILER: - iov[i].buffer.length = - krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER); - size += iov[i].buffer.length; - break; - case GSS_IOV_BUFFER_TYPE_PADDING: - if (padding != NULL) { - *minor_status = 0; - return GSS_S_FAILURE; - } - padding = &iov[i].buffer.length; - break; - case GSS_IOV_BUFFER_TYPE_STREAM: - size += iov[i].buffer.length; - break; - case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: - break; - default: - *minor_status = EINVAL; - return GSS_S_FAILURE; - } - } - if (padding) { - size_t pad = krb5_crypto_length(context, ctx->crypto, - KRB5_CRYPTO_TYPE_PADDING); - if (pad > 1) { - *padding = pad - (size % pad); - if (*padding == pad) - *padding = 0; - } else - *padding = 0; - } - - return GSS_S_COMPLETE; + + if (ctx->more_flags & IS_CFX) + return _gssapi_wrap_iov_length_cfx(minor_status, ctx, context, + conf_req_flag, qop_req, conf_state, + iov, iov_count); + + return GSS_S_FAILURE; } diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c index b48cfebcf1..e7331b0119 100644 --- a/source4/heimdal/lib/gssapi/krb5/arcfour.c +++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* * Implements draft-brezak-win2k-krb-rc4-hmac-04.txt * diff --git a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c index 3a206b1be1..7e0c3fe727 100644 --- a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c +++ b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_canonicalize_name ( OM_uint32 * minor_status, const gss_name_t input_name, diff --git a/source4/heimdal/lib/gssapi/krb5/cfx.c b/source4/heimdal/lib/gssapi/krb5/cfx.c index 7ae26e2e7a..35e5a9e45a 100755 --- a/source4/heimdal/lib/gssapi/krb5/cfx.c +++ b/source4/heimdal/lib/gssapi/krb5/cfx.c @@ -32,10 +32,8 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* - * Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt + * Implementation of RFC 4121 */ #define CFXSentByAcceptor (1 << 0) @@ -101,13 +99,14 @@ _gsskrb5cfx_wrap_length_cfx(const gsskrb5_ctx context_handle, return 0; } -OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status, - const gsskrb5_ctx ctx, - krb5_context context, - int conf_req_flag, - gss_qop_t qop_req, - OM_uint32 req_output_size, - OM_uint32 *max_input_size) +OM_uint32 +_gssapi_wrap_size_cfx(OM_uint32 *minor_status, + const gsskrb5_ctx ctx, + krb5_context context, + int conf_req_flag, + gss_qop_t qop_req, + OM_uint32 req_output_size, + OM_uint32 *max_input_size) { krb5_error_code ret; @@ -203,11 +202,763 @@ rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate) return 0; } +gss_iov_buffer_desc * +_gk_find_buffer(gss_iov_buffer_desc *iov, int iov_count, OM_uint32 type) +{ + int i; + + for (i = 0; i < iov_count; i++) + if (type == GSS_IOV_BUFFER_TYPE(iov[i].type)) + return &iov[i]; + return NULL; +} + +static OM_uint32 +allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t size) +{ + if (buffer->type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) { + if (buffer->buffer.length == size) + return GSS_S_COMPLETE; + free(buffer->buffer.value); + } + + buffer->buffer.value = malloc(size); + buffer->buffer.length = size; + if (buffer->buffer.value == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + buffer->type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED; + + return GSS_S_COMPLETE; +} + + + +OM_uint32 +_gssapi_wrap_cfx_iov(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + krb5_context context, + int conf_req_flag, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + OM_uint32 major_status, junk; + gss_iov_buffer_desc *header, *trailer, *padding; + size_t gsshsize, k5hsize; + size_t gsstsize, k5tsize; + size_t i, padlength, rrc = 0, ec = 0; + gss_cfx_wrap_token token; + krb5_error_code ret; + int32_t seq_number; + unsigned usage; + krb5_crypto_iov *data = NULL; + int paddingoffset = 0; + + header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + if (header == NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &padlength); + + padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); + if (padlength != 0 && padding == NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + + if (conf_req_flag) { + ec = padlength; + + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize); + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize); + + gsshsize = k5hsize + sizeof(*token); + gsstsize = k5tsize + sizeof(*token); /* encrypted token stored in trailer */ + + } else { + + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_CHECKSUM, &k5tsize); + + gsshsize = sizeof(*token); + gsstsize = k5tsize; + } + + /* + * + */ + + if (trailer == NULL) { + /* conf_req_flag=0 doesn't support DCE_STYLE */ + if (conf_req_flag == 0) { + *minor_status = EINVAL; + major_status = GSS_S_FAILURE; + goto failure; + } + rrc = gsstsize; + if (IS_DCE_STYLE(ctx)) + rrc -= ec; + gsshsize += gsstsize; + gsstsize = 0; + } else if (GSS_IOV_BUFFER_FLAGS(trailer->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) { + major_status = allocate_buffer(minor_status, trailer, gsstsize); + if (major_status) + goto failure; + } else if (trailer->buffer.length < gsstsize) { + *minor_status = KRB5_BAD_MSIZE; + major_status = GSS_S_FAILURE; + goto failure; + } else + trailer->buffer.length = gsstsize; + + /* + * + */ + + if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) { + major_status = allocate_buffer(minor_status, header, gsshsize); + if (major_status != GSS_S_COMPLETE) + goto failure; + } else if (header->buffer.length < gsshsize) { + *minor_status = KRB5_BAD_MSIZE; + major_status = GSS_S_FAILURE; + goto failure; + } else + header->buffer.length = gsshsize; + + token = (gss_cfx_wrap_token)header->buffer.value; + + token->TOK_ID[0] = 0x05; + token->TOK_ID[1] = 0x04; + token->Flags = 0; + token->Filler = 0xFF; + + if (ctx->more_flags & ACCEPTOR_SUBKEY) + token->Flags |= CFXAcceptorSubkey; + + if (ctx->more_flags & LOCAL) + usage = KRB5_KU_USAGE_INITIATOR_SEAL; + else + usage = KRB5_KU_USAGE_ACCEPTOR_SEAL; + + if (conf_req_flag) { + /* + * In Wrap tokens with confidentiality, the EC field is + * used to encode the size (in bytes) of the random filler. + */ + token->Flags |= CFXSealed; + token->EC[0] = (padlength >> 8) & 0xFF; + token->EC[1] = (padlength >> 0) & 0xFF; + + } else { + /* + * In Wrap tokens without confidentiality, the EC field is + * used to encode the size (in bytes) of the trailing + * checksum. + * + * This is not used in the checksum calcuation itself, + * because the checksum length could potentially vary + * depending on the data length. + */ + token->EC[0] = 0; + token->EC[1] = 0; + } + + /* + * In Wrap tokens that provide for confidentiality, the RRC + * field in the header contains the hex value 00 00 before + * encryption. + * + * In Wrap tokens that do not provide for confidentiality, + * both the EC and RRC fields in the appended checksum + * contain the hex value 00 00 for the purpose of calculating + * the checksum. + */ + token->RRC[0] = 0; + token->RRC[1] = 0; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + krb5_auth_con_getlocalseqnumber(context, + ctx->auth_context, + &seq_number); + _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]); + _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]); + krb5_auth_con_setlocalseqnumber(context, + ctx->auth_context, + ++seq_number); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + data = calloc(iov_count + 3, sizeof(data[0])); + if (data == NULL) { + *minor_status = ENOMEM; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (conf_req_flag) { + /* + plain packet: + + {"header" | encrypt(plaintext-data | padding | E"header")} + + Expanded, this is with with RRC = 0: + + {"header" | krb5-header | plaintext-data | padding | E"header" | krb5-trailer } + + In DCE-RPC mode == no trailer: RRC = gss "trailer" == length(padding | E"header" | krb5-trailer) + + {"header" | padding | E"header" | krb5-trailer | krb5-header | plaintext-data } + */ + + i = 0; + data[i].flags = KRB5_CRYPTO_TYPE_HEADER; + data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize; + data[i].data.length = k5hsize; + + for (i = 1; i < iov_count + 1; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i - 1].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + break; + case GSS_IOV_BUFFER_TYPE_PADDING: + data[i].flags = KRB5_CRYPTO_TYPE_PADDING; + paddingoffset = i; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + break; + default: + data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; + break; + } + data[i].data.length = iov[i - 1].buffer.length; + data[i].data.data = iov[i - 1].buffer.value; + } + + /* + * Any necessary padding is added here to ensure that the + * encrypted token header is always at the end of the + * ciphertext. + */ + + /* XXX KRB5_CRYPTO_TYPE_PADDING */ + + /* encrypted CFX header in trailer (or after the header if in + DCE mode). Copy in header into E"header" + */ + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + if (trailer) + data[i].data.data = trailer->buffer.value; + else + data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token); + + data[i].data.length = sizeof(*token); + memcpy(data[i].data.data, token, sizeof(*token)); + i++; + + /* Kerberos trailer comes after the gss trailer */ + data[i].flags = KRB5_CRYPTO_TYPE_TRAILER; + data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token); + data[i].data.length = k5tsize; + i++; + + ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL); + if (ret != 0) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (rrc) { + token->RRC[0] = (rrc >> 8) & 0xFF; + token->RRC[1] = (rrc >> 0) & 0xFF; + } + + if (paddingoffset) + padding->buffer.length = data[paddingoffset].data.length; + + } else { + /* + plain packet: + + {data | "header" | gss-trailer (krb5 checksum) + + don't do RRC != 0 + + */ + + for (i = 0; i < iov_count; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + case GSS_IOV_BUFFER_TYPE_PADDING: + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + break; + default: + data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; + break; + } + data[i].data.length = iov[i].buffer.length; + data[i].data.data = iov[i].buffer.value; + } + + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + data[i].data.data = header->buffer.value; + data[i].data.length = header->buffer.length; + i++; + + data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM; + data[i].data.data = trailer->buffer.value; + data[i].data.length = trailer->buffer.length; + i++; + + ret = krb5_create_checksum_iov(context, ctx->crypto, usage, data, i, NULL); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto failure; + } + + token->EC[0] = (trailer->buffer.length >> 8) & 0xFF; + token->EC[1] = (trailer->buffer.length >> 0) & 0xFF; + } + + if (conf_state != NULL) + *conf_state = conf_req_flag; + + free(data); + + *minor_status = 0; + return GSS_S_COMPLETE; + + failure: + if (data) + free(data); + + gss_release_iov_buffer(&junk, iov, iov_count); + + return major_status; +} + +/* This is slowpath */ +static OM_uint32 +unrotate_iov(OM_uint32 *minor_status, size_t rrc, gss_iov_buffer_desc *iov, int iov_count) +{ + uint8_t *p, *q; + size_t len = 0, skip; + int i; + + for (i = 0; i < iov_count; i++) + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER) + len += iov[i].buffer.length; + + p = malloc(len); + if (p == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + q = p; + + /* copy up */ + + for (i = 0; i < iov_count; i++) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER) + { + memcpy(q, iov[i].buffer.value, iov[i].buffer.length); + q += iov[i].buffer.length; + } + } + assert((q - p) == len); + + /* unrotate first part */ + q = p + rrc; + skip = rrc; + for (i = 0; i < iov_count; i++) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER) + { + if (iov[i].buffer.length <= skip) { + skip -= iov[i].buffer.length; + } else { + memcpy(((uint8_t *)iov[i].buffer.value) + skip, q, iov[i].buffer.length - skip); + q += iov[i].buffer.length - skip; + skip = 0; + } + } + } + /* copy trailer */ + q = p; + skip = rrc; + for (i = 0; i < iov_count; i++) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER) + { + memcpy(q, iov[i].buffer.value, MIN(iov[i].buffer.length, skip)); + if (iov[i].buffer.length > skip) + break; + skip -= iov[i].buffer.length; + q += iov[i].buffer.length; + } + } + return GSS_S_COMPLETE; +} + + +OM_uint32 +_gssapi_unwrap_cfx_iov(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + krb5_context context, + int *conf_state, + gss_qop_t *qop_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + OM_uint32 seq_number_lo, seq_number_hi, major_status, junk; + gss_iov_buffer_desc *header, *trailer; + gss_cfx_wrap_token token, ttoken; + u_char token_flags; + krb5_error_code ret; + unsigned usage; + uint16_t ec, rrc; + krb5_crypto_iov *data = NULL; + int i, j; + + *minor_status = 0; + + header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + if (header == NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + if (header->buffer.length < sizeof(*token)) /* we check exact below */ + return GSS_S_DEFECTIVE_TOKEN; + + trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + + token = (gss_cfx_wrap_token)header->buffer.value; + + if (token->TOK_ID[0] != 0x05 || token->TOK_ID[1] != 0x04) + return GSS_S_DEFECTIVE_TOKEN; + + /* Ignore unknown flags */ + token_flags = token->Flags & + (CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey); + + if (token_flags & CFXSentByAcceptor) { + if ((ctx->more_flags & LOCAL) == 0) + return GSS_S_DEFECTIVE_TOKEN; + } + + if (ctx->more_flags & ACCEPTOR_SUBKEY) { + if ((token_flags & CFXAcceptorSubkey) == 0) + return GSS_S_DEFECTIVE_TOKEN; + } else { + if (token_flags & CFXAcceptorSubkey) + return GSS_S_DEFECTIVE_TOKEN; + } + + if (token->Filler != 0xFF) + return GSS_S_DEFECTIVE_TOKEN; + + if (conf_state != NULL) + *conf_state = (token_flags & CFXSealed) ? 1 : 0; + + ec = (token->EC[0] << 8) | token->EC[1]; + rrc = (token->RRC[0] << 8) | token->RRC[1]; + + /* + * Check sequence number + */ + _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi); + _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo); + if (seq_number_hi) { + /* no support for 64-bit sequence numbers */ + *minor_status = ERANGE; + return GSS_S_UNSEQ_TOKEN; + } + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + ret = _gssapi_msg_order_check(ctx->order, seq_number_lo); + if (ret != 0) { + *minor_status = 0; + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return ret; + } + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + /* + * Decrypt and/or verify checksum + */ + + if (ctx->more_flags & LOCAL) { + usage = KRB5_KU_USAGE_ACCEPTOR_SEAL; + } else { + usage = KRB5_KU_USAGE_INITIATOR_SEAL; + } + + data = calloc(iov_count + 3, sizeof(data[0])); + if (data == NULL) { + *minor_status = ENOMEM; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (token_flags & CFXSealed) { + size_t k5tsize, k5hsize; + + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize); + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize); + + /* Rotate by RRC; bogus to do this in-place XXX */ + /* Check RRC */ + + if (trailer == NULL) { + size_t gsstsize = k5tsize + sizeof(*token); + size_t gsshsize = k5hsize + sizeof(*token); + + if (IS_DCE_STYLE(ctx)) + gsstsize += ec; + gsshsize += gsstsize; + + if (rrc != gsstsize) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto failure; + } + if (header->buffer.length != gsshsize) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto failure; + } + } else if (trailer->buffer.length != sizeof(*token) + k5tsize) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto failure; + } else if (header->buffer.length != sizeof(*token) + k5hsize) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto failure; + } else if (rrc != 0) { + /* go though slowpath */ + major_status = unrotate_iov(minor_status, rrc, iov, iov_count); + if (major_status) + goto failure; + } + + i = 0; + data[i].flags = KRB5_CRYPTO_TYPE_HEADER; + data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize; + data[i].data.length = k5hsize; + i++; + + for (j = 0; j < iov_count; i++, j++) { + switch (GSS_IOV_BUFFER_TYPE(iov[j].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + case GSS_IOV_BUFFER_TYPE_PADDING: + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + break; + default: + data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; + break; + } + data[i].data.length = iov[j].buffer.length; + data[i].data.data = iov[j].buffer.value; + } + + /* encrypted CFX header in trailer (or after the header if in + DCE mode). Copy in header into E"header" + */ + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + if (trailer) + data[i].data.data = trailer->buffer.value; + else + data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token); + data[i].data.length = sizeof(*token); + ttoken = (gss_cfx_wrap_token)data[i].data.data; + i++; + + /* Kerberos trailer comes after the gss trailer */ + data[i].flags = KRB5_CRYPTO_TYPE_TRAILER; + data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token); + data[i].data.length = k5tsize; + i++; + + ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL); + if (ret != 0) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto failure; + } + + ttoken->RRC[0] = token->RRC[0]; + ttoken->RRC[1] = token->RRC[1]; + + /* Check the integrity of the header */ + if (memcmp(ttoken, token, sizeof(*token)) != 0) { + major_status = GSS_S_BAD_MIC; + goto failure; + } + } else { + /* Check RRC */ + if (rrc != 0) { + *minor_status = EINVAL; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (trailer == NULL) { + *minor_status = EINVAL; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (trailer->buffer.length != ec) { + *minor_status = EINVAL; + major_status = GSS_S_FAILURE; + goto failure; + } + + for (i = 0; i < iov_count; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + case GSS_IOV_BUFFER_TYPE_PADDING: + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + break; + default: + data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; + break; + } + data[i].data.length = iov[i].buffer.length; + data[i].data.data = iov[i].buffer.value; + } + + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + data[i].data.data = header->buffer.value; + data[i].data.length = header->buffer.length; + i++; + + data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM; + data[i].data.data = trailer->buffer.value; + data[i].data.length = trailer->buffer.length; + i++; + + token = (gss_cfx_wrap_token)header->buffer.value; + token->EC[0] = 0; + token->EC[1] = 0; + token->RRC[0] = 0; + token->RRC[1] = 0; + + ret = krb5_verify_checksum_iov(context, ctx->crypto, usage, data, i, NULL); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto failure; + } + } + + if (qop_state != NULL) { + *qop_state = GSS_C_QOP_DEFAULT; + } + + free(data); + + *minor_status = 0; + return GSS_S_COMPLETE; + + failure: + if (data) + free(data); + + gss_release_iov_buffer(&junk, iov, iov_count); + + return major_status; +} + +OM_uint32 +_gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + krb5_context context, + int conf_req_flag, + gss_qop_t qop_req, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + size_t size; + int i; + size_t *padding = NULL; + + GSSAPI_KRB5_INIT (&context); + *minor_status = 0; + + for (size = 0, i = 0; i < iov_count; i++) { + switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_EMPTY: + break; + case GSS_IOV_BUFFER_TYPE_DATA: + size += iov[i].buffer.length; + break; + case GSS_IOV_BUFFER_TYPE_HEADER: + *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &iov[i].buffer.length); + if (*minor_status) + return GSS_S_FAILURE; + break; + case GSS_IOV_BUFFER_TYPE_TRAILER: + *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &iov[i].buffer.length); + if (*minor_status) + return GSS_S_FAILURE; + break; + case GSS_IOV_BUFFER_TYPE_PADDING: + if (padding != NULL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + padding = &iov[i].buffer.length; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + break; + default: + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + } + if (padding) { + size_t pad; + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &pad); + if (pad > 1) { + *padding = pad - (size % pad); + if (*padding == pad) + *padding = 0; + } else + *padding = 0; + } + + return GSS_S_COMPLETE; +} + + + + OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, const gsskrb5_ctx ctx, krb5_context context, int conf_req_flag, - gss_qop_t qop_req, const gss_buffer_t input_message_buffer, int *conf_state, gss_buffer_t output_message_buffer) diff --git a/source4/heimdal/lib/gssapi/krb5/compare_name.c b/source4/heimdal/lib/gssapi/krb5/compare_name.c index fbb0f0218e..f45e4df3e2 100644 --- a/source4/heimdal/lib/gssapi/krb5/compare_name.c +++ b/source4/heimdal/lib/gssapi/krb5/compare_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_compare_name (OM_uint32 * minor_status, const gss_name_t name1, diff --git a/source4/heimdal/lib/gssapi/krb5/compat.c b/source4/heimdal/lib/gssapi/krb5/compat.c index 012602c074..221d219c69 100644 --- a/source4/heimdal/lib/gssapi/krb5/compat.c +++ b/source4/heimdal/lib/gssapi/krb5/compat.c @@ -33,9 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - - static krb5_error_code check_compat(OM_uint32 *minor_status, krb5_context context, krb5_const_principal name, diff --git a/source4/heimdal/lib/gssapi/krb5/context_time.c b/source4/heimdal/lib/gssapi/krb5/context_time.c index 3230389938..987ceea4aa 100644 --- a/source4/heimdal/lib/gssapi/krb5/context_time.c +++ b/source4/heimdal/lib/gssapi/krb5/context_time.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_lifetime_left(OM_uint32 *minor_status, krb5_context context, diff --git a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c index 40a8fab1b7..a4b28f91ed 100644 --- a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c +++ b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - #if 0 OM_uint32 gss_krb5_copy_ccache(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c index a2a5de9fe7..7ccf0b0f79 100644 --- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c +++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* * return the length of the mechanism in token or -1 * (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN diff --git a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c index ea0831815a..b3d436ea01 100644 --- a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_delete_sec_context(OM_uint32 * minor_status, gss_ctx_id_t * context_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/display_name.c b/source4/heimdal/lib/gssapi/krb5/display_name.c index 0b37731510..6487d84880 100644 --- a/source4/heimdal/lib/gssapi/krb5/display_name.c +++ b/source4/heimdal/lib/gssapi/krb5/display_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_display_name (OM_uint32 * minor_status, const gss_name_t input_name, diff --git a/source4/heimdal/lib/gssapi/krb5/display_status.c b/source4/heimdal/lib/gssapi/krb5/display_status.c index 4136c25e53..f9d84fc762 100644 --- a/source4/heimdal/lib/gssapi/krb5/display_status.c +++ b/source4/heimdal/lib/gssapi/krb5/display_status.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static const char * calling_error(OM_uint32 v) { diff --git a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c index 2b5e5c0ef4..b0188acd51 100644 --- a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c +++ b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_duplicate_name ( OM_uint32 * minor_status, const gss_name_t src_name, diff --git a/source4/heimdal/lib/gssapi/krb5/encapsulate.c b/source4/heimdal/lib/gssapi/krb5/encapsulate.c index 838a34d7db..79cd9232e1 100644 --- a/source4/heimdal/lib/gssapi/krb5/encapsulate.c +++ b/source4/heimdal/lib/gssapi/krb5/encapsulate.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - void _gssapi_encap_length (size_t data_len, size_t *len, diff --git a/source4/heimdal/lib/gssapi/krb5/export_name.c b/source4/heimdal/lib/gssapi/krb5/export_name.c index bad73611dc..705bb70d91 100644 --- a/source4/heimdal/lib/gssapi/krb5/export_name.c +++ b/source4/heimdal/lib/gssapi/krb5/export_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_export_name (OM_uint32 * minor_status, const gss_name_t input_name, diff --git a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c index 305d5c334e..3d3870a6b4 100644 --- a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_export_sec_context ( OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c index 1c28f7c141..df23776a63 100644 --- a/source4/heimdal/lib/gssapi/krb5/external.c +++ b/source4/heimdal/lib/gssapi/krb5/external.c @@ -34,8 +34,6 @@ #include "gsskrb5_locl.h" #include -RCSID("$Id$"); - /* * The implementation must reserve static storage for a * gss_OID_desc object containing the value diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c index 66aaba44d6..ad3009c73e 100644 --- a/source4/heimdal/lib/gssapi/krb5/get_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static OM_uint32 mic_des (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/import_name.c b/source4/heimdal/lib/gssapi/krb5/import_name.c index 8f5387fe2b..d488ce754b 100644 --- a/source4/heimdal/lib/gssapi/krb5/import_name.c +++ b/source4/heimdal/lib/gssapi/krb5/import_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static OM_uint32 parse_krb5_name (OM_uint32 *minor_status, krb5_context context, diff --git a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c index ba1a977d2d..2af942338f 100644 --- a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_import_sec_context ( OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c index 3702106e79..b1d18bd244 100644 --- a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c +++ b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_indicate_mechs (OM_uint32 * minor_status, gss_OID_set * mech_set diff --git a/source4/heimdal/lib/gssapi/krb5/init.c b/source4/heimdal/lib/gssapi/krb5/init.c index b28e6a4c12..3a22c33ed6 100644 --- a/source4/heimdal/lib/gssapi/krb5/init.c +++ b/source4/heimdal/lib/gssapi/krb5/init.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER; static int created_key; static HEIMDAL_thread_key context_key; diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c index 4b632bd95a..35ab9dd88d 100644 --- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* * copy the addresses from `input_chan_bindings' (if any) to * the auth context `ac' @@ -697,7 +695,7 @@ repl_mutual if (actual_mech_type) *actual_mech_type = GSS_KRB5_MECHANISM; - if (ctx->flags & GSS_C_DCE_STYLE) { + if (IS_DCE_STYLE(ctx)) { /* There is no OID wrapping. */ indata.length = input_token->length; indata.data = input_token->value; diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_context.c b/source4/heimdal/lib/gssapi/krb5/inquire_context.c index 188a6135a4..381ffc9e6f 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_context.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_inquire_context ( OM_uint32 * minor_status, const gss_ctx_id_t context_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c index 27e3014923..518736d78e 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_inquire_cred (OM_uint32 * minor_status, const gss_cred_id_t cred_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c index 1fd9733940..9da1ac43f1 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_inquire_cred_by_mech ( OM_uint32 * minor_status, const gss_cred_id_t cred_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c index 5a35202a6a..f32342f1d8 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c @@ -32,8 +32,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_inquire_cred_by_oid (OM_uint32 * minor_status, const gss_cred_id_t cred_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c index 5d54bd6508..5fa3c302a2 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_inquire_mechs_for_name ( OM_uint32 * minor_status, const gss_name_t input_name, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c index 9eba7b7f4d..591343307e 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c @@ -33,9 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - - static gss_OID *name_list[] = { &GSS_C_NT_HOSTBASED_SERVICE, &GSS_C_NT_USER_NAME, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c index f8ef2a3aa4..ce01e666fa 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c @@ -32,8 +32,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static int oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix) { diff --git a/source4/heimdal/lib/gssapi/krb5/prf.c b/source4/heimdal/lib/gssapi/krb5/prf.c index 9fd13f51bd..76ae3b78ed 100644 --- a/source4/heimdal/lib/gssapi/krb5/prf.c +++ b/source4/heimdal/lib/gssapi/krb5/prf.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_pseudo_random(OM_uint32 *minor_status, gss_ctx_id_t context_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/process_context_token.c b/source4/heimdal/lib/gssapi/krb5/process_context_token.c index 3229b36292..1c9d44588f 100644 --- a/source4/heimdal/lib/gssapi/krb5/process_context_token.c +++ b/source4/heimdal/lib/gssapi/krb5/process_context_token.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_process_context_token ( OM_uint32 *minor_status, const gss_ctx_id_t context_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/release_buffer.c b/source4/heimdal/lib/gssapi/krb5/release_buffer.c index 18e0279939..b704e001eb 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_buffer.c +++ b/source4/heimdal/lib/gssapi/krb5/release_buffer.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_release_buffer (OM_uint32 * minor_status, gss_buffer_t buffer diff --git a/source4/heimdal/lib/gssapi/krb5/release_cred.c b/source4/heimdal/lib/gssapi/krb5/release_cred.c index 62674a1d53..5eec3c48cb 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/release_cred.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_release_cred (OM_uint32 * minor_status, gss_cred_id_t * cred_handle diff --git a/source4/heimdal/lib/gssapi/krb5/release_name.c b/source4/heimdal/lib/gssapi/krb5/release_name.c index 5491052c59..0fafc275d0 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_name.c +++ b/source4/heimdal/lib/gssapi/krb5/release_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_release_name (OM_uint32 * minor_status, gss_name_t * input_name diff --git a/source4/heimdal/lib/gssapi/krb5/sequence.c b/source4/heimdal/lib/gssapi/krb5/sequence.c index 6391d44429..fbbc5b6c70 100644 --- a/source4/heimdal/lib/gssapi/krb5/sequence.c +++ b/source4/heimdal/lib/gssapi/krb5/sequence.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - #define DEFAULT_JITTER_WINDOW 20 struct gss_msg_order { diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c index 2a2390f8d1..15d7632e4c 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c @@ -32,8 +32,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* 1.2.752.43.13.17 */ static gss_OID_desc gss_krb5_cred_no_ci_flags_x_oid_desc = {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")}; diff --git a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c index 460cfe942a..096e835045 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c @@ -36,8 +36,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static OM_uint32 get_bool(OM_uint32 *minor_status, const gss_buffer_t value, diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c index 0e87cb88b7..20cf952b4e 100644 --- a/source4/heimdal/lib/gssapi/krb5/unwrap.c +++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static OM_uint32 unwrap_des (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c index 6eb7ae4b08..c7e16e81f7 100644 --- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static OM_uint32 verify_mic_des (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c index b9f4c237c7..3de13f908f 100644 --- a/source4/heimdal/lib/gssapi/krb5/wrap.c +++ b/source4/heimdal/lib/gssapi/krb5/wrap.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* * Return initiator subkey, or if that doesn't exists, the subkey. */ @@ -540,7 +538,7 @@ OM_uint32 _gsskrb5_wrap if (ctx->more_flags & IS_CFX) return _gssapi_wrap_cfx (minor_status, ctx, context, conf_req_flag, - qop_req, input_message_buffer, conf_state, + input_message_buffer, conf_state, output_message_buffer); HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); diff --git a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c index a8ebe644ab..b1bc7dd981 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c @@ -50,7 +50,7 @@ gss_acquire_cred(OM_uint32 *minor_status, int i; *minor_status = 0; - if (output_cred_handle) + if (output_cred_handle == NULL) return GSS_S_CALL_INACCESSIBLE_READ; if (actual_mechs) *actual_mechs = GSS_C_NO_OID_SET; diff --git a/source4/heimdal/lib/gssapi/mech/gss_aeap.c b/source4/heimdal/lib/gssapi/mech/gss_aeap.c index cbe0cd1460..9c784f42de 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_aeap.c +++ b/source4/heimdal/lib/gssapi/mech/gss_aeap.c @@ -3,27 +3,39 @@ */ #include "mech_locl.h" -RCSID("$Id$"); /** * Encrypts or sign the data. * + * This is a more complicated version of gss_wrap(), it allows the + * caller to use AEAD data (signed header/trailer) and allow greater + * controll over where the encrypted data is placed. + * * The maximum packet size is gss_context_stream_sizes.max_msg_size. * - * The caller needs provide the folloing buffers: + * The caller needs provide the folloing buffers when using in conf_req_flag=1 mode: * * - HEADER (of size gss_context_stream_sizes.header) - * SIGN_ONLY (optional, zero or more) - * DATA - * SIGN_ONLY (optional, zero or more) - * PADDING (of size gss_context_stream_sizes.blocksize) + * { DATA or SIGN_ONLY } (optional, zero or more) + * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted) * TRAILER (of size gss_context_stream_sizes.trailer) * * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the - * DATA elements is padded to a block bountry. + * DATA elements is padded to a block bountry and header is of at + * least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer. + * + * HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large. * * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER * + * When used in conf_req_flag=0, + * + * - HEADER (of size gss_context_stream_sizes.header) + * { DATA or SIGN_ONLY } (optional, zero or more) + * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted) + * TRAILER (of size gss_context_stream_sizes.trailer) + * + * * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or * gss_context_query_attributes(). * @@ -65,6 +77,13 @@ gss_wrap_iov(OM_uint32 * minor_status, iov, iov_count); } +/** + * Decrypt or verifies the signature on the data. + * + * + * @ingroup gssapi + */ + OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, @@ -99,7 +118,18 @@ gss_unwrap_iov(OM_uint32 *minor_status, iov, iov_count); } -OM_uint32 GSSAPI_LIB_FUNCTION +/** + * Update the length fields in iov buffer for the types: + * - GSS_IOV_BUFFER_TYPE_HEADER + * - GSS_IOV_BUFFER_TYPE_PADDING + * - GSS_IOV_BUFFER_TYPE_TRAILER + * + * Consider using gss_context_query_attributes() to fetch the data instead. + * + * @ingroup gssapi + */ + +OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_iov_length(OM_uint32 * minor_status, gss_ctx_id_t context_handle, int conf_req_flag, @@ -132,6 +162,13 @@ gss_wrap_iov_length(OM_uint32 * minor_status, iov, iov_count); } +/** + * Free all buffer allocated by gss_wrap_iov() or gss_unwrap_iov() by + * looking at the GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED flag. + * + * @ingroup gssapi + */ + OM_uint32 GSSAPI_LIB_FUNCTION gss_release_iov_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, @@ -146,9 +183,10 @@ gss_release_iov_buffer(OM_uint32 *minor_status, return GSS_S_CALL_INACCESSIBLE_READ; for (i = 0; i < iov_count; i++) { - if (iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) + if ((iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) == 0) continue; gss_release_buffer(&junk, &iov[i].buffer); + iov[i].type &= ~GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED; } return GSS_S_COMPLETE; } @@ -159,6 +197,8 @@ gss_release_iov_buffer(OM_uint32 *minor_status, * SSPI equivalent if this function is QueryContextAttributes. * * - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes. + * + * @ingroup gssapi */ static gss_OID_desc gss_c_attr_stream_sizes_desc = diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c index 158126d99f..2bdfc28ebf 100644 --- a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c @@ -92,12 +92,6 @@ send_supported_mechs (OM_uint32 *minor_status, gss_buffer_t output_token) { NegotiationTokenWin nt; - char hostname[MAXHOSTNAMELEN + 1], *p; - gss_buffer_desc name_buf; - gss_OID name_type; - gss_name_t target_princ; - gss_name_t canon_princ; - OM_uint32 minor; size_t buf_len; gss_buffer_desc data; OM_uint32 ret; @@ -116,62 +110,9 @@ send_supported_mechs (OM_uint32 *minor_status, return ret; } - memset(&target_princ, 0, sizeof(target_princ)); - if (gethostname(hostname, sizeof(hostname) - 2) != 0) { - *minor_status = errno; - free_NegotiationTokenWin(&nt); - return GSS_S_FAILURE; - } - hostname[sizeof(hostname) - 1] = '\0'; - - /* Send the constructed SAM name for this host */ - for (p = hostname; *p != '\0' && *p != '.'; p++) { - *p = toupper((unsigned char)*p); - } - *p++ = '$'; - *p = '\0'; - - name_buf.length = strlen(hostname); - name_buf.value = hostname; - - ret = gss_import_name(minor_status, &name_buf, - GSS_C_NO_OID, - &target_princ); - if (ret != GSS_S_COMPLETE) { - free_NegotiationTokenWin(&nt); - return ret; - } - - name_buf.length = 0; - name_buf.value = NULL; - - /* Canonicalize the name using the preferred mechanism */ - ret = gss_canonicalize_name(minor_status, - target_princ, - GSS_C_NO_OID, - &canon_princ); - if (ret != GSS_S_COMPLETE) { - free_NegotiationTokenWin(&nt); - gss_release_name(&minor, &target_princ); - return ret; - } - - ret = gss_display_name(minor_status, canon_princ, - &name_buf, &name_type); - if (ret != GSS_S_COMPLETE) { - free_NegotiationTokenWin(&nt); - gss_release_name(&minor, &canon_princ); - gss_release_name(&minor, &target_princ); - return ret; - } - - gss_release_name(&minor, &canon_princ); - gss_release_name(&minor, &target_princ); - ALLOC(nt.u.negTokenInit.negHints, 1); if (nt.u.negTokenInit.negHints == NULL) { *minor_status = ENOMEM; - gss_release_buffer(&minor, &name_buf); free_NegotiationTokenWin(&nt); return GSS_S_FAILURE; } @@ -179,20 +120,19 @@ send_supported_mechs (OM_uint32 *minor_status, ALLOC(nt.u.negTokenInit.negHints->hintName, 1); if (nt.u.negTokenInit.negHints->hintName == NULL) { *minor_status = ENOMEM; - gss_release_buffer(&minor, &name_buf); free_NegotiationTokenWin(&nt); return GSS_S_FAILURE; } - *(nt.u.negTokenInit.negHints->hintName) = name_buf.value; - name_buf.value = NULL; + *nt.u.negTokenInit.negHints->hintName = strdup("not_defined_in_RFC4178@please_ignore"); nt.u.negTokenInit.negHints->hintAddress = NULL; ASN1_MALLOC_ENCODE(NegotiationTokenWin, data.value, data.length, &nt, &buf_len, ret); free_NegotiationTokenWin(&nt); if (ret) { - return ret; + *minor_status = ret; + return GSS_S_FAILURE; } if (data.length != buf_len) abort(); diff --git a/source4/heimdal/lib/hdb/db.c b/source4/heimdal/lib/hdb/db.c index 556833d1c4..9de0a04a1f 100644 --- a/source4/heimdal/lib/hdb/db.c +++ b/source4/heimdal/lib/hdb/db.c @@ -33,8 +33,6 @@ #include "hdb_locl.h" -RCSID("$Id$"); - #if HAVE_DB1 #if defined(HAVE_DB_185_H) @@ -317,6 +315,7 @@ hdb_db_create(krb5_context context, HDB **db, } (*db)->hdb_master_key_set = 0; (*db)->hdb_openp = 0; + (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL; (*db)->hdb_open = DB_open; (*db)->hdb_close = DB_close; (*db)->hdb_fetch = _hdb_fetch; diff --git a/source4/heimdal/lib/hdb/dbinfo.c b/source4/heimdal/lib/hdb/dbinfo.c index 7e2961c614..a399ab0a5c 100644 --- a/source4/heimdal/lib/hdb/dbinfo.c +++ b/source4/heimdal/lib/hdb/dbinfo.c @@ -33,8 +33,6 @@ #include "hdb_locl.h" -RCSID("$Id$"); - struct hdb_dbinfo { char *label; char *realm; diff --git a/source4/heimdal/lib/hdb/ext.c b/source4/heimdal/lib/hdb/ext.c index 9053fd6633..faf0b6bdf2 100644 --- a/source4/heimdal/lib/hdb/ext.c +++ b/source4/heimdal/lib/hdb/ext.c @@ -34,8 +34,6 @@ #include "hdb_locl.h" #include -RCSID("$Id$"); - krb5_error_code hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent) { diff --git a/source4/heimdal/lib/hdb/hdb.asn1 b/source4/heimdal/lib/hdb/hdb.asn1 index c2abd4af73..a72851c9f2 100644 --- a/source4/heimdal/lib/hdb/hdb.asn1 +++ b/source4/heimdal/lib/hdb/hdb.asn1 @@ -45,7 +45,9 @@ HDBFlags ::= BIT STRING { immutable(13), -- may not be deleted trusted-for-delegation(14), -- Trusted to print forwardabled tickets allow-kerberos4(15), -- Allow Kerberos 4 requests - allow-digest(16) -- Allow digest requests + allow-digest(16), -- Allow digest requests + locked-out(17) -- Account is locked out, + -- authentication will be denied } GENERATION ::= SEQUENCE { diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c index e55b0bed03..9795f8b255 100644 --- a/source4/heimdal/lib/hdb/hdb.c +++ b/source4/heimdal/lib/hdb/hdb.c @@ -33,7 +33,6 @@ #include "krb5_locl.h" #include "hdb_locl.h" -RCSID("$Id$"); #ifdef HAVE_DLFCN_H #include diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h index a5e6514e6c..f490dbf2f0 100644 --- a/source4/heimdal/lib/hdb/hdb.h +++ b/source4/heimdal/lib/hdb/hdb.h @@ -54,7 +54,15 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; #define HDB_F_GET_ANY 28 /* fetch any of client,server,krbtgt */ #define HDB_F_CANON 32 /* want canonicalition */ +/* hdb_capability_flags */ #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1 +#define HDB_CAP_F_HANDLE_PASSWORDS 2 +#define HDB_CAP_F_PASSWORD_UPDATE_KEYS 4 + +/* auth status values */ +#define HDB_AUTH_SUCCESS 0 +#define HDB_AUTH_WRONG_PASSWORD 1 +#define HDB_AUTH_INVALID_SIGNATURE 2 /* key usage for master key */ #define HDB_KU_MKEY 0x484442 @@ -184,6 +192,34 @@ typedef struct HDB{ * point for the module. */ krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*); + /** + * Change password. + * + * Will update keys for the entry when given password. The new + * keys must be written into the entry and and will then later be + * ->hdb_store() into the database. The backend will still perform + * all other operations, increasing the kvno, and update + * modification timestamp. + * + * The backen need to call _kadm5_set_keys() and perform password + * quality checks. + */ + krb5_error_code (*hdb_password)(krb5_context, struct HDB*, hdb_entry_ex*, const char *, int); + + /** + * Auth feedback + * + * This is a feedback call that allows backends that provides + * lockout functionality to register failure and/or successes. + * + * In case the entry is locked out, the backend should set the + * hdb_entry.flags.locked-out flag. + */ + krb5_error_code (*hdb_auth_status)(krb5_context, struct HDB *, hdb_entry_ex *, int); + /** + * Check is delegation is allowed. + */ + krb5_error_code (*hdb_check_constrained_delegation)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal); }HDB; #define HDB_INTERFACE_VERSION 5 diff --git a/source4/heimdal/lib/hdb/keys.c b/source4/heimdal/lib/hdb/keys.c index 50fe7d7fda..63f254d002 100644 --- a/source4/heimdal/lib/hdb/keys.c +++ b/source4/heimdal/lib/hdb/keys.c @@ -34,8 +34,6 @@ #include "hdb_locl.h" -RCSID("$Id$"); - /* * free all the memory used by (len, keys) */ diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c index 97989a9764..9b36a268cf 100644 --- a/source4/heimdal/lib/hdb/keytab.c +++ b/source4/heimdal/lib/hdb/keytab.c @@ -35,8 +35,6 @@ /* keytab backend for HDB databases */ -RCSID("$Id$"); - struct hdb_data { char *dbname; char *mkey; @@ -123,61 +121,43 @@ hdb_get_name(krb5_context context, return 0; } -static void -set_config (krb5_context context, - const krb5_config_binding *binding, - const char **dbname, - const char **mkey) -{ - *dbname = krb5_config_get_string(context, binding, "dbname", NULL); - *mkey = krb5_config_get_string(context, binding, "mkey_file", NULL); -} - /* * try to figure out the database (`dbname') and master-key (`mkey') * that should be used for `principal'. */ -static void +static krb5_error_code find_db (krb5_context context, - const char **dbname, - const char **mkey, + char **dbname, + char **mkey, krb5_const_principal principal) { - const krb5_config_binding *top_bind = NULL; - const krb5_config_binding *default_binding = NULL; - const krb5_config_binding *db; krb5_const_realm realm = krb5_principal_get_realm(context, principal); + krb5_error_code ret; + struct hdb_dbinfo *head, *dbinfo = NULL; *dbname = *mkey = NULL; - while ((db = - krb5_config_get_next(context, - NULL, - &top_bind, - krb5_config_list, - "kdc", - "database", - NULL)) != NULL) { - const char *p; - - p = krb5_config_get_string (context, db, "realm", NULL); - if (p == NULL) { - if(default_binding) { - krb5_warnx(context, "WARNING: more than one realm-less " - "database specification"); - krb5_warnx(context, "WARNING: using the first encountered"); - } else - default_binding = db; - } else if (strcmp (realm, p) == 0) { - set_config (context, db, dbname, mkey); + ret = hdb_get_dbinfo(context, &head); + if (ret) + return ret; + + while ((dbinfo = hdb_dbinfo_get_next(head, dbinfo)) != NULL) { + const char *p = hdb_dbinfo_get_realm(context, dbinfo); + if (p && strcmp (realm, p) == 0) { + p = hdb_dbinfo_get_dbname(context, dbinfo); + if (p) + *dbname = strdup(p); + p = hdb_dbinfo_get_mkey_file(context, dbinfo); + if (p) + *mkey = strdup(p); break; } } - if (*dbname == NULL && default_binding != NULL) - set_config (context, default_binding, dbname, mkey); + hdb_free_dbinfo(context, &head); if (*dbname == NULL) - *dbname = HDB_DEFAULT_DB; + *dbname = strdup(HDB_DEFAULT_DB); + return 0; } /* @@ -196,29 +176,35 @@ hdb_get_entry(krb5_context context, hdb_entry_ex ent; krb5_error_code ret; struct hdb_data *d = id->data; - int i; - HDB *db; const char *dbname = d->dbname; const char *mkey = d->mkey; + char *fdbname = NULL, *fmkey = NULL; + HDB *db; + int i; memset(&ent, 0, sizeof(ent)); - if (dbname == NULL) - find_db (context, &dbname, &mkey, principal); + if (dbname == NULL) { + ret = find_db(context, &fdbname, &fmkey, principal); + if (ret) + return ret; + dbname = fdbname; + mkey = fmkey; + } ret = hdb_create (context, &db, dbname); if (ret) - return ret; + goto out2; ret = hdb_set_master_keyfile (context, db, mkey); if (ret) { (*db->hdb_destroy)(context, db); - return ret; + goto out2; } ret = (*db->hdb_open)(context, db, O_RDONLY, 0); if (ret) { (*db->hdb_destroy)(context, db); - return ret; + goto out2; } ret = (*db->hdb_fetch)(context, db, principal, HDB_F_DECRYPT| @@ -252,9 +238,12 @@ hdb_get_entry(krb5_context context, } } hdb_free_entry(context, &ent); -out: + out: (*db->hdb_close)(context, db); (*db->hdb_destroy)(context, db); + out2: + free(fdbname); + free(fmkey); return ret; } diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c index 1520c4f7e9..35323cf100 100644 --- a/source4/heimdal/lib/hdb/mkey.c +++ b/source4/heimdal/lib/hdb/mkey.c @@ -36,8 +36,6 @@ #define O_BINARY 0 #endif -RCSID("$Id$"); - struct hdb_master_key_data { krb5_keytab_entry keytab; krb5_crypto crypto; diff --git a/source4/heimdal/lib/hdb/ndbm.c b/source4/heimdal/lib/hdb/ndbm.c index 1e9df81652..d97a98ed6b 100644 --- a/source4/heimdal/lib/hdb/ndbm.c +++ b/source4/heimdal/lib/hdb/ndbm.c @@ -33,8 +33,6 @@ #include "hdb_locl.h" -RCSID("$Id$"); - #if HAVE_NDBM #if defined(HAVE_GDBM_NDBM_H) @@ -348,6 +346,7 @@ hdb_ndbm_create(krb5_context context, HDB **db, } (*db)->hdb_master_key_set = 0; (*db)->hdb_openp = 0; + (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL; (*db)->hdb_open = NDBM_open; (*db)->hdb_close = NDBM_close; (*db)->hdb_fetch = _hdb_fetch; diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c index 8063100717..f4667c6e31 100644 --- a/source4/heimdal/lib/hx509/crypto.c +++ b/source4/heimdal/lib/hx509/crypto.c @@ -37,10 +37,6 @@ struct hx509_crypto; struct signature_alg; -enum crypto_op_type { - COT_SIGN -}; - struct hx509_generate_private_context { const heim_oid *key_oid; int isCA; diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index 9fd2117345..a30780d1ed 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -3182,7 +3182,7 @@ krb5_encrypt_iov_ivec(krb5_context context, krb5_error_code ret; struct key_data *dkey; const struct encryption_type *et = crypto->et; - krb5_crypto_iov *tiv, *piv, *hiv, *div; + krb5_crypto_iov *tiv, *piv, *hiv; if (num_data < 0) { krb5_clear_error_message(context); @@ -3197,11 +3197,11 @@ krb5_encrypt_iov_ivec(krb5_context context, headersz = et->confoundersize; trailersz = CHECKSUMSIZE(et->keyed_checksum); - div = find_iv(data, num_data, KRB5_CRYPTO_TYPE_DATA); - if (div == NULL) - return KRB5_CRYPTO_INTERNAL; - - len = div->data.length; + for (len = 0, i = 0; i < num_data; i++) { + if (data[i].flags != KRB5_CRYPTO_TYPE_DATA) + continue; + len += data[i].data.length; + } sz = headersz + len; block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */ @@ -3217,7 +3217,6 @@ krb5_encrypt_iov_ivec(krb5_context context, krb5_generate_random_block(hiv->data.data, hiv->data.length); /* padding */ - piv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_PADDING); /* its ok to have no TYPE_PADDING if there is no padding */ if (piv == NULL && pad_sz != 0) @@ -3226,26 +3225,26 @@ krb5_encrypt_iov_ivec(krb5_context context, if (piv->data.length < pad_sz) return KRB5_BAD_MSIZE; piv->data.length = pad_sz; + if (pad_sz) + memset(piv->data.data, pad_sz, pad_sz); + else + piv = NULL; } - /* trailer */ - tiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); if (tiv == NULL || tiv->data.length != trailersz) return KRB5_BAD_MSIZE; - /* * XXX replace with EVP_Sign? at least make create_checksum an iov * function. * XXX CTS EVP is broken, can't handle multi buffers :( */ - len = hiv->data.length; + len = block_sz; for (i = 0; i < num_data; i++) { - if (data[i].flags != KRB5_CRYPTO_TYPE_DATA && - data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY) + if (data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY) continue; len += data[i].data.length; } @@ -3261,6 +3260,10 @@ krb5_encrypt_iov_ivec(krb5_context context, memcpy(q, data[i].data.data, data[i].data.length); q += data[i].data.length; } + if (piv) { + memset(q, 0, piv->data.length); + q += piv->data.length; + } ret = create_checksum(context, et->keyed_checksum, @@ -3282,30 +3285,24 @@ krb5_encrypt_iov_ivec(krb5_context context, memcpy(tiv->data.data, cksum.checksum.data, cksum.checksum.length); free_Checksum (&cksum); - /* now encrypt data */ - - ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); - if(ret) - return ret; - ret = _key_schedule(context, dkey); - if(ret) - return ret; - /* XXX replace with EVP_Cipher */ - - len = hiv->data.length + div->data.length; - if (piv) - len += piv->data.length; - - p = q = malloc(len); + p = q = malloc(block_sz); if(p == NULL) return ENOMEM; memcpy(q, hiv->data.data, hiv->data.length); q += hiv->data.length; - memcpy(q, div->data.data, div->data.length); - q += div->data.length; - memset(q, 0, pad_sz); + + for (i = 0; i < num_data; i++) { + if (data[i].flags != KRB5_CRYPTO_TYPE_DATA) + continue; + memcpy(q, data[i].data.data, data[i].data.length); + q += data[i].data.length; + } + if (piv) { + memset(q, 0, piv->data.length); + q += piv->data.length; + } ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); if(ret) { @@ -3318,7 +3315,7 @@ krb5_encrypt_iov_ivec(krb5_context context, return ret; } - ret = (*et->encrypt)(context, dkey, p, len, 1, usage, ivec); + ret = (*et->encrypt)(context, dkey, p, block_sz, 1, usage, ivec); if (ret) { free(p); return ret; @@ -3330,11 +3327,17 @@ krb5_encrypt_iov_ivec(krb5_context context, memcpy(hiv->data.data, q, hiv->data.length); q += hiv->data.length; - memcpy(div->data.data, q, div->data.length); - q += div->data.length; - - if (piv) + for (i = 0; i < num_data; i++) { + if (data[i].flags != KRB5_CRYPTO_TYPE_DATA) + continue; + memcpy(data[i].data.data, q, data[i].data.length); + q += data[i].data.length; + } + if (piv) { memcpy(piv->data.data, q, pad_sz); + q += pad_sz; + } + free(p); return ret; @@ -3371,13 +3374,12 @@ krb5_decrypt_iov_ivec(krb5_context context, { unsigned int i; size_t headersz, trailersz, len; - size_t sz, block_sz, pad_sz; Checksum cksum; unsigned char *p, *q; krb5_error_code ret; struct key_data *dkey; struct encryption_type *et = crypto->et; - krb5_crypto_iov *tiv, *hiv, *div; + krb5_crypto_iov *tiv, *hiv; if (num_data < 0) { krb5_clear_error_message(context); @@ -3390,56 +3392,47 @@ krb5_decrypt_iov_ivec(krb5_context context, } headersz = et->confoundersize; - trailersz = CHECKSUMSIZE(et->keyed_checksum); - - for (len = 0, i = 0; i < num_data; i++) { - if (data[i].flags == KRB5_CRYPTO_TYPE_DATA) { - if (len != 0) - return KRB5_CRYPTO_INTERNAL; - len += data[i].data.length; - } - } - - sz = headersz + len; - block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */ - - pad_sz = block_sz - sz; - trailersz += pad_sz; - - /* header */ hiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_HEADER); - if (hiv == NULL || hiv->data.length < headersz) + if (hiv == NULL || hiv->data.length != headersz) return KRB5_BAD_MSIZE; - hiv->data.length = headersz; /* trailer */ + trailersz = CHECKSUMSIZE(et->keyed_checksum); tiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); - if (tiv == NULL || tiv->data.length < trailersz) + if (tiv->data.length != trailersz) return KRB5_BAD_MSIZE; - tiv->data.length = trailersz; - - div = find_iv(data, num_data, KRB5_CRYPTO_TYPE_DATA); - if (div == NULL) - return KRB5_CRYPTO_INTERNAL; - /* XXX replace with EVP_Cipher */ + /* Find length of data we will decrypt */ - for (len = 0, i = 0; i < num_data; i++) { - if (data[i].flags != KRB5_CRYPTO_TYPE_HEADER && - data[i].flags != KRB5_CRYPTO_TYPE_DATA) + len = headersz; + for (i = 0; i < num_data; i++) { + if (data[i].flags != KRB5_CRYPTO_TYPE_DATA) continue; len += data[i].data.length; } + if ((len % et->padsize) != 0) { + krb5_clear_error_message(context); + return KRB5_BAD_MSIZE; + } + + /* XXX replace with EVP_Cipher */ + p = q = malloc(len); if (p == NULL) return ENOMEM; memcpy(q, hiv->data.data, hiv->data.length); q += hiv->data.length; - memcpy(q, div->data.data, div->data.length); + + for (i = 0; i < num_data; i++) { + if (data[i].flags != KRB5_CRYPTO_TYPE_DATA) + continue; + memcpy(q, data[i].data.data, data[i].data.length); + q += data[i].data.length; + } ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); if(ret) { @@ -3460,20 +3453,26 @@ krb5_decrypt_iov_ivec(krb5_context context, /* copy data back to buffers */ memcpy(hiv->data.data, p, hiv->data.length); - memcpy(div->data.data, p + hiv->data.length, len - hiv->data.length); + q = p + hiv->data.length; + for (i = 0; i < num_data; i++) { + if (data[i].flags != KRB5_CRYPTO_TYPE_DATA) + continue; + memcpy(data[i].data.data, q, data[i].data.length); + q += data[i].data.length; + } + free(p); /* check signature */ - - len = hiv->data.length; for (i = 0; i < num_data; i++) { - if (data[i].flags != KRB5_CRYPTO_TYPE_DATA && - data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY) + if (data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY) continue; len += data[i].data.length; } p = q = malloc(len); + if (p == NULL) + return ENOMEM; memcpy(q, hiv->data.data, hiv->data.length); q += hiv->data.length; @@ -3582,33 +3581,145 @@ krb5_create_checksum_iov(krb5_context context, return 0; } +/** + * Verify a Kerberos message checksum. + * + * @param context Kerberos context + * @param crypto Kerberos crypto context + * @param usage Key usage for this buffer + * @param data array of buffers to process + * @param num_data length of array + * + * @return Return an error code or 0. + * @ingroup krb5_crypto + */ + +krb5_error_code KRB5_LIB_FUNCTION +krb5_verify_checksum_iov(krb5_context context, + krb5_crypto crypto, + unsigned usage, + krb5_crypto_iov *data, + unsigned int num_data, + krb5_cksumtype *type) +{ + struct encryption_type *et = crypto->et; + Checksum cksum; + krb5_crypto_iov *civ; + krb5_error_code ret; + int i; + size_t len; + char *p, *q; + + if (num_data < 0) { + krb5_clear_error_message(context); + return KRB5_CRYPTO_INTERNAL; + } + + if(!derived_crypto(context, crypto)) { + krb5_clear_error_message(context); + return KRB5_CRYPTO_INTERNAL; + } + + civ = find_iv(data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM); + if (civ == NULL) + return KRB5_BAD_MSIZE; + + len = 0; + for (i = 0; i < num_data; i++) { + if (data[i].flags != KRB5_CRYPTO_TYPE_DATA && + data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY) + continue; + len += data[i].data.length; + } + + p = q = malloc(len); + + for (i = 0; i < num_data; i++) { + if (data[i].flags != KRB5_CRYPTO_TYPE_DATA && + data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY) + continue; + memcpy(q, data[i].data.data, data[i].data.length); + q += data[i].data.length; + } + + cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum); + cksum.checksum.length = civ->data.length; + cksum.checksum.data = civ->data.data; + + ret = krb5_verify_checksum(context, crypto, usage, p, len, &cksum); + free(p); + + if (ret == 0 && type) + *type = cksum.cksumtype; + + return ret; +} + -size_t KRB5_LIB_FUNCTION +krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_length(krb5_context context, krb5_crypto crypto, - int type) + int type, + size_t *len) { - if (!derived_crypto(context, crypto)) - return (size_t)-1; + if (!derived_crypto(context, crypto)) { + krb5_set_error_message(context, EINVAL, "not a derived crypto"); + return EINVAL; + } + switch(type) { case KRB5_CRYPTO_TYPE_EMPTY: + *len = 0; return 0; case KRB5_CRYPTO_TYPE_HEADER: - return crypto->et->blocksize; + *len = crypto->et->blocksize; + return 0; + case KRB5_CRYPTO_TYPE_DATA: + case KRB5_CRYPTO_TYPE_SIGN_ONLY: + /* len must already been filled in */ + return 0; case KRB5_CRYPTO_TYPE_PADDING: if (crypto->et->padsize > 1) - return crypto->et->padsize; + *len = crypto->et->padsize; + else + *len = 0; return 0; case KRB5_CRYPTO_TYPE_TRAILER: - return CHECKSUMSIZE(crypto->et->keyed_checksum); + *len = CHECKSUMSIZE(crypto->et->keyed_checksum); + return 0; case KRB5_CRYPTO_TYPE_CHECKSUM: if (crypto->et->keyed_checksum) - return CHECKSUMSIZE(crypto->et->keyed_checksum); - return CHECKSUMSIZE(crypto->et->checksum); + *len = CHECKSUMSIZE(crypto->et->keyed_checksum); + else + *len = CHECKSUMSIZE(crypto->et->checksum); + return 0; + } + krb5_set_error_message(context, EINVAL, + "%d not a supported type", type); + return EINVAL; +} + + +krb5_error_code KRB5_LIB_FUNCTION +krb5_crypto_length_iov(krb5_context context, + krb5_crypto crypto, + krb5_crypto_iov *data, + unsigned int num_data) +{ + krb5_error_code ret; + int i; + + for (i = 0; i < num_data; i++) { + ret = krb5_crypto_length(context, crypto, + data[i].flags, + &data[i].data.length); + if (ret) + return ret; } - return (size_t)-1; + return 0; } + krb5_error_code KRB5_LIB_FUNCTION krb5_encrypt_ivec(krb5_context context, krb5_crypto crypto, diff --git a/source4/heimdal/lib/krb5/get_addrs.c b/source4/heimdal/lib/krb5/get_addrs.c index 96571af531..8f366fa148 100644 --- a/source4/heimdal/lib/krb5/get_addrs.c +++ b/source4/heimdal/lib/krb5/get_addrs.c @@ -41,9 +41,7 @@ struct mbuf; #ifdef HAVE_NET_IF_H #include #endif -#ifdef HAVE_IFADDR_H #include -#endif static krb5_error_code gethostname_fallback (krb5_context context, krb5_addresses *res) diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index 0435ab5d3b..ff89a90d55 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -1601,7 +1601,7 @@ krb5_init_creds_step(krb5_context context, ret = 0; } else if (ret == KRB5_KDC_ERR_WRONG_REALM && ctx->flags.canonicalize) { /* client referal to a new realm */ - if (ctx->error.crealm) { + if (ctx->error.crealm == NULL) { krb5_set_error_message(context, ret, N_("Got a client referral, not but no realm", "")); goto out; diff --git a/source4/heimdal/lib/krb5/store_emem.c b/source4/heimdal/lib/krb5/store_emem.c index 4be89b6564..acf984280e 100644 --- a/source4/heimdal/lib/krb5/store_emem.c +++ b/source4/heimdal/lib/krb5/store_emem.c @@ -110,7 +110,12 @@ emem_trunc(krb5_storage *sp, off_t offset) * If offset is larget then current size, or current size is * shrunk more then half of the current size, adjust buffer. */ - if (offset > s->size || (s->size / 2) > offset) { + if (offset == 0) { + free(s->base); + s->size = 0; + s->base = NULL; + s->ptr = NULL; + } else if (offset > s->size || (s->size / 2) > offset) { void *base; size_t off; off = s->ptr - s->base; -- cgit From c901f57ce31cb6deaf2897e12b3b14a25fe9e12f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Jul 2009 12:34:55 +1000 Subject: s4:kdc Initialise new hdb function pointers. Soon we will add implementations for these. --- source4/kdc/hdb-samba4.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 84050edb7c..21e8c9a38e 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -1468,6 +1468,9 @@ NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx, (*db)->hdb__del = NULL; (*db)->hdb_destroy = LDB_destroy; + (*db)->hdb_auth_status = NULL; + (*db)->hdb_check_constrained_delegation = NULL; + return NT_STATUS_OK; } -- cgit From 1f12dc4409cc4964e708c29906fad1f81086ec01 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2009 08:20:17 +0200 Subject: tsocket: rename sa_len => sa_socklen, because sa_len is a macro on some platforms metze --- lib/tsocket/tsocket_bsd.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c index 78bca4b0b5..8f1ccbeb43 100644 --- a/lib/tsocket/tsocket_bsd.c +++ b/lib/tsocket/tsocket_bsd.c @@ -203,7 +203,7 @@ struct tsocket_address_bsd { static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, struct sockaddr *sa, - socklen_t sa_len, + socklen_t sa_socklen, struct tsocket_address **_addr, const char *location) { @@ -212,20 +212,20 @@ static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, switch (sa->sa_family) { case AF_UNIX: - if (sa_len < sizeof(struct sockaddr_un)) { + if (sa_socklen < sizeof(struct sockaddr_un)) { errno = EINVAL; return -1; } break; case AF_INET: - if (sa_len < sizeof(struct sockaddr_in)) { + if (sa_socklen < sizeof(struct sockaddr_in)) { errno = EINVAL; return -1; } break; #ifdef HAVE_IPV6 case AF_INET6: - if (sa_len < sizeof(struct sockaddr_in6)) { + if (sa_socklen < sizeof(struct sockaddr_in6)) { errno = EINVAL; return -1; } @@ -236,7 +236,7 @@ static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, return -1; } - if (sa_len > sizeof(struct sockaddr_storage)) { + if (sa_socklen > sizeof(struct sockaddr_storage)) { errno = EINVAL; return -1; } @@ -253,7 +253,7 @@ static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, ZERO_STRUCTP(bsda); - memcpy(&bsda->u.ss, sa, sa_len); + memcpy(&bsda->u.ss, sa, sa_socklen); *_addr = addr; return 0; @@ -773,7 +773,7 @@ static void tdgram_bsd_recvfrom_handler(void *private_data) struct tsocket_address_bsd *bsda; ssize_t ret; struct sockaddr *sa = NULL; - socklen_t sa_len = 0; + socklen_t sa_socklen = 0; int err; bool retry; @@ -809,16 +809,16 @@ static void tdgram_bsd_recvfrom_handler(void *private_data) ZERO_STRUCTP(bsda); sa = &bsda->u.sa; - sa_len = sizeof(bsda->u.ss); + sa_socklen = sizeof(bsda->u.ss); /* * for unix sockets we can't use the size of sockaddr_storage * we would get EINVAL */ if (bsda->u.sa.sa_family == AF_UNIX) { - sa_len = sizeof(bsda->u.un); + sa_socklen = sizeof(bsda->u.un); } - ret = recvfrom(bsds->fd, state->buf, state->len, 0, sa, &sa_len); + ret = recvfrom(bsds->fd, state->buf, state->len, 0, sa, &sa_socklen); err = tsocket_bsd_error_from_errno(ret, errno, &retry); if (retry) { /* retry later */ @@ -946,7 +946,7 @@ static void tdgram_bsd_sendto_handler(void *private_data) struct tdgram_context *dgram = state->dgram; struct tdgram_bsd *bsds = tdgram_context_data(dgram, struct tdgram_bsd); struct sockaddr *sa = NULL; - socklen_t sa_len = 0; + socklen_t sa_socklen = 0; ssize_t ret; int err; bool retry; @@ -957,17 +957,17 @@ static void tdgram_bsd_sendto_handler(void *private_data) struct tsocket_address_bsd); sa = &bsda->u.sa; - sa_len = sizeof(bsda->u.ss); + sa_socklen = sizeof(bsda->u.ss); /* * for unix sockets we can't use the size of sockaddr_storage * we would get EINVAL */ if (bsda->u.sa.sa_family == AF_UNIX) { - sa_len = sizeof(bsda->u.un); + sa_socklen = sizeof(bsda->u.un); } } - ret = sendto(bsds->fd, state->buf, state->len, 0, sa, sa_len); + ret = sendto(bsds->fd, state->buf, state->len, 0, sa, sa_socklen); err = tsocket_bsd_error_from_errno(ret, errno, &retry); if (retry) { /* retry later */ @@ -1087,7 +1087,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, int ret; bool do_bind = false; bool do_reuseaddr = false; - socklen_t sa_len = sizeof(lbsda->u.ss); + socklen_t sa_socklen = sizeof(lbsda->u.ss); if (remote) { rbsda = talloc_get_type_abort(remote->private_data, @@ -1108,7 +1108,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, * for unix sockets we can't use the size of sockaddr_storage * we would get EINVAL */ - sa_len = sizeof(lbsda->u.un); + sa_socklen = sizeof(lbsda->u.un); break; case AF_INET: if (lbsda->u.in.sin_port != 0) { @@ -1189,7 +1189,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, } if (do_bind) { - ret = bind(fd, &lbsda->u.sa, sa_len); + ret = bind(fd, &lbsda->u.sa, sa_socklen); if (ret == -1) { int saved_errno = errno; talloc_free(dgram); @@ -1199,7 +1199,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, } if (rbsda) { - ret = connect(fd, &rbsda->u.sa, sa_len); + ret = connect(fd, &rbsda->u.sa, sa_socklen); if (ret == -1) { int saved_errno = errno; talloc_free(dgram); @@ -1889,7 +1889,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, bool retry; bool do_bind = false; bool do_reuseaddr = false; - socklen_t sa_len = sizeof(rbsda->u.ss); + socklen_t sa_socklen = sizeof(rbsda->u.ss); req = tevent_req_create(mem_ctx, &state, struct tstream_bsd_connect_state); @@ -1917,7 +1917,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, * for unix sockets we can't use the size of sockaddr_storage * we would get EINVAL */ - sa_len = sizeof(rbsda->u.un); + sa_socklen = sizeof(rbsda->u.un); break; case AF_INET: if (lbsda->u.in.sin_port != 0) { @@ -1977,7 +1977,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, } } - ret = connect(state->fd, &rbsda->u.sa, sa_len); + ret = connect(state->fd, &rbsda->u.sa, sa_socklen); err = tsocket_bsd_error_from_errno(ret, errno, &retry); if (retry) { /* retry later */ -- cgit From 3fa212af61cd334daf2b0ac6bb4c85e1db15230a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2009 08:51:51 +0200 Subject: s4:heimdal_build: try to fix the build on Solaris The problem seems to be #define flock rk_flock heimdal/../heimdal_build/replace.c: In function `rk_flock': heimdal/../heimdal_build/replace.c:64: error: storage size of 'lock' isn't known heimdal/../heimdal_build/replace.c:64: warning: unused variable `lock' metze --- source4/heimdal_build/replace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/heimdal_build/replace.c b/source4/heimdal_build/replace.c index 6842b11f96..8c3def7dca 100644 --- a/source4/heimdal_build/replace.c +++ b/source4/heimdal_build/replace.c @@ -61,6 +61,7 @@ #ifndef HAVE_FLOCK int flock(int fd, int op) { +#undef flock struct flock lock; lock.l_whence = 0; lock.l_start = 0; -- cgit From 29c3a277e10e9c87c6965c4c6fb26a01b1277c57 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 00:56:17 +0200 Subject: s4-smbtorture: move all trusted domain tests to RPC-LSA-TRUSTED-DOMAINS. Guenther --- source4/torture/rpc/lsa.c | 55 +++++++++++++++++++++++++++++++++++++++++------ source4/torture/rpc/rpc.c | 1 + 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 7d03e7ef9e..1794a033bc 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -2632,13 +2632,6 @@ bool torture_rpc_lsa(struct torture_context *tctx) if (!test_CreateSecret(p, tctx, handle)) { ret = false; } - if (!test_CreateTrustedDomain(p, tctx, handle)) { - ret = false; - } - - if (!test_CreateTrustedDomainEx2(p, tctx, handle)) { - ret = false; - } if (!test_EnumAccounts(p, tctx, handle)) { ret = false; @@ -2766,3 +2759,51 @@ struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx) return suite; } + +static bool testcase_TrustedDomains(struct torture_context *tctx, + struct dcerpc_pipe *p) +{ + bool ret = true; + struct policy_handle *handle; + + if (!test_OpenPolicy(p, tctx)) { + ret = false; + } + + if (!test_lsa_OpenPolicy2(p, tctx, &handle)) { + ret = false; + } + + if (!handle) { + ret = false; + } + + if (!test_CreateTrustedDomain(p, tctx, handle)) { + ret = false; + } + + if (!test_CreateTrustedDomainEx2(p, tctx, handle)) { + ret = false; + } + + if (!test_lsa_Close(p, tctx, handle)) { + ret = false; + } + + return ret; +} + +struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite; + struct torture_rpc_tcase *tcase; + + suite = torture_suite_create(mem_ctx, "LSA-TRUSTED-DOMAINS"); + + tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa", + &ndr_table_lsarpc); + torture_rpc_tcase_add_test(tcase, "TrustedDomains", + testcase_TrustedDomains); + + return suite; +} diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c index 6eeba7f66c..94297088c3 100644 --- a/source4/torture/rpc/rpc.c +++ b/source4/torture/rpc/rpc.c @@ -431,6 +431,7 @@ NTSTATUS torture_rpc_init(void) torture_suite_add_suite(suite, torture_rpc_lsa_lookup_sids(suite)); torture_suite_add_suite(suite, torture_rpc_lsa_lookup_names(suite)); torture_suite_add_suite(suite, torture_rpc_lsa_secrets(suite)); + torture_suite_add_suite(suite, torture_rpc_lsa_trusted_domains(suite)); torture_suite_add_suite(suite, torture_rpc_echo(suite)); torture_suite_add_simple_test(suite, "DFS", torture_rpc_dfs); torture_suite_add_suite(suite, torture_rpc_frsapi(suite)); -- cgit From 47eb061b5345cccf322c165f510f54c04481d4bc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 02:10:23 +0200 Subject: s4-smbtorture: move all privilege tests to RPC-LSA-PRIVILEGES. Guenther --- source4/torture/rpc/lsa.c | 65 ++++++++++++++++++++++++++++++++++++++--------- source4/torture/rpc/rpc.c | 1 + 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 1794a033bc..801bc8711e 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -2625,22 +2625,10 @@ bool torture_rpc_lsa(struct torture_context *tctx) ret = false; } - if (!test_CreateAccount(p, tctx, handle)) { - ret = false; - } - if (!test_CreateSecret(p, tctx, handle)) { ret = false; } - if (!test_EnumAccounts(p, tctx, handle)) { - ret = false; - } - - if (!test_EnumPrivs(p, tctx, handle)) { - ret = false; - } - if (!test_QueryInfoPolicy(p, tctx, handle)) { ret = false; } @@ -2807,3 +2795,56 @@ struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx) return suite; } + +static bool testcase_Privileges(struct torture_context *tctx, + struct dcerpc_pipe *p) +{ + bool ret = true; + struct policy_handle *handle; + + if (!test_OpenPolicy(p, tctx)) { + ret = false; + } + + if (!test_lsa_OpenPolicy2(p, tctx, &handle)) { + ret = false; + } + + if (!handle) { + ret = false; + } + + if (!test_CreateAccount(p, tctx, handle)) { + ret = false; + } + + if (!test_EnumAccounts(p, tctx, handle)) { + ret = false; + } + + if (!test_EnumPrivs(p, tctx, handle)) { + ret = false; + } + + if (!test_lsa_Close(p, tctx, handle)) { + ret = false; + } + + return ret; +} + + +struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite; + struct torture_rpc_tcase *tcase; + + suite = torture_suite_create(mem_ctx, "LSA-PRIVILEGES"); + + tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa", + &ndr_table_lsarpc); + torture_rpc_tcase_add_test(tcase, "Privileges", + testcase_Privileges); + + return suite; +} diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c index 94297088c3..ffdd748470 100644 --- a/source4/torture/rpc/rpc.c +++ b/source4/torture/rpc/rpc.c @@ -432,6 +432,7 @@ NTSTATUS torture_rpc_init(void) torture_suite_add_suite(suite, torture_rpc_lsa_lookup_names(suite)); torture_suite_add_suite(suite, torture_rpc_lsa_secrets(suite)); torture_suite_add_suite(suite, torture_rpc_lsa_trusted_domains(suite)); + torture_suite_add_suite(suite, torture_rpc_lsa_privileges(suite)); torture_suite_add_suite(suite, torture_rpc_echo(suite)); torture_suite_add_simple_test(suite, "DFS", torture_rpc_dfs); torture_suite_add_suite(suite, torture_rpc_frsapi(suite)); -- cgit From 3c9b26276083002124674678ac757e859fb6b20e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 11:07:06 +0200 Subject: fix LSA-TRUSTED-DOMAINS --- source4/torture/rpc/lsa.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 801bc8711e..c4eea4be4a 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -2788,8 +2788,9 @@ struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx) suite = torture_suite_create(mem_ctx, "LSA-TRUSTED-DOMAINS"); - tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa", - &ndr_table_lsarpc); + tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "lsa", + &ndr_table_lsarpc, + TEST_MACHINENAME); torture_rpc_tcase_add_test(tcase, "TrustedDomains", testcase_TrustedDomains); -- cgit From 0d9fdbceedddb08dbea8ed84e06a218d3ec562f4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 11:07:14 +0200 Subject: fix LSA-PRIVILEGES --- source4/torture/rpc/lsa.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index c4eea4be4a..b8b9ced660 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -2842,8 +2842,9 @@ struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx) suite = torture_suite_create(mem_ctx, "LSA-PRIVILEGES"); - tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa", - &ndr_table_lsarpc); + tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "lsa", + &ndr_table_lsarpc, + TEST_MACHINENAME); torture_rpc_tcase_add_test(tcase, "Privileges", testcase_Privileges); -- cgit From 8cac8fd5d69f332db9e50865395d11e36639904f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 11:13:26 +0200 Subject: s4-smbtorture: use torture_comment in RPC-LSA tests. Guenther --- source4/torture/rpc/lsa.c | 408 +++++++++++++++++++++++----------------------- 1 file changed, 204 insertions(+), 204 deletions(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index b8b9ced660..7963092cb9 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -47,7 +47,7 @@ static bool test_OpenPolicy(struct dcerpc_pipe *p, NTSTATUS status; uint16_t system_name = '\\'; - printf("\nTesting OpenPolicy\n"); + torture_comment(tctx, "\nTesting OpenPolicy\n"); qos.len = 0; qos.impersonation_level = 2; @@ -70,10 +70,10 @@ static bool test_OpenPolicy(struct dcerpc_pipe *p, if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) { - printf("not considering %s to be an error\n", nt_errstr(status)); + torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status)); return true; } - printf("OpenPolicy failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "OpenPolicy failed - %s\n", nt_errstr(status)); return false; } @@ -90,7 +90,7 @@ bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p, struct lsa_OpenPolicy2 r; NTSTATUS status; - printf("\nTesting OpenPolicy2\n"); + torture_comment(tctx, "\nTesting OpenPolicy2\n"); *handle = talloc(tctx, struct policy_handle); if (!*handle) { @@ -118,12 +118,12 @@ bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p, if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) { - printf("not considering %s to be an error\n", nt_errstr(status)); + torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status)); talloc_free(*handle); *handle = NULL; return true; } - printf("OpenPolicy2 failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(status)); return false; } @@ -161,7 +161,7 @@ static bool test_LookupNames(struct dcerpc_pipe *p, NTSTATUS status; int i; - printf("\nTesting LookupNames with %d names\n", tnames->count); + torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count); sids.count = 0; sids.sids = NULL; @@ -187,30 +187,30 @@ static bool test_LookupNames(struct dcerpc_pipe *p, NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) { for (i=0;i< tnames->count;i++) { if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) { - printf("LookupName of %s was unmapped\n", + torture_comment(tctx, "LookupName of %s was unmapped\n", tnames->names[i].name.string); } else if (i >=count) { - printf("LookupName of %s failed to return a result\n", + torture_comment(tctx, "LookupName of %s failed to return a result\n", tnames->names[i].name.string); } } - printf("LookupNames failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status)); return false; } else if (!NT_STATUS_IS_OK(status)) { - printf("LookupNames failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status)); return false; } for (i=0;i< tnames->count;i++) { if (i < count && sids.sids[i].sid_type != tnames->names[i].sid_type) { - printf("LookupName of %s got unexpected name type: %s\n", + torture_comment(tctx, "LookupName of %s got unexpected name type: %s\n", tnames->names[i].name.string, sid_type_lookup(sids.sids[i].sid_type)); } else if (i >=count) { - printf("LookupName of %s failed to return a result\n", + torture_comment(tctx, "LookupName of %s failed to return a result\n", tnames->names[i].name.string); } } - printf("\n"); + torture_comment(tctx, "\n"); return true; } @@ -235,7 +235,7 @@ static bool test_LookupNames_bogus(struct dcerpc_pipe *p, name[0].name.string = "NT AUTHORITY\\BOGUS"; name[1].name.string = NULL; - printf("\nTesting LookupNames with bogus names\n"); + torture_comment(tctx, "\nTesting LookupNames with bogus names\n"); sids.count = 0; sids.sids = NULL; @@ -257,11 +257,11 @@ static bool test_LookupNames_bogus(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupNames(p, tctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) { - printf("LookupNames failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status)); return false; } - printf("\n"); + torture_comment(tctx, "\n"); return true; } @@ -274,7 +274,7 @@ static bool test_LookupNames_wellknown(struct dcerpc_pipe *p, struct lsa_TransNameArray tnames; bool ret = true; - printf("Testing LookupNames with well known names\n"); + torture_comment(tctx, "Testing LookupNames with well known names\n"); tnames.names = &name; tnames.count = 1; @@ -330,7 +330,7 @@ static bool test_LookupNames2(struct dcerpc_pipe *p, NTSTATUS status; int i; - printf("\nTesting LookupNames2 with %d names\n", tnames->count); + torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count); sids.count = 0; sids.sids = NULL; @@ -354,7 +354,7 @@ static bool test_LookupNames2(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupNames2(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("LookupNames2 failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "LookupNames2 failed - %s\n", nt_errstr(status)); return false; } @@ -366,7 +366,7 @@ static bool test_LookupNames2(struct dcerpc_pipe *p, } } - printf("\n"); + torture_comment(tctx, "\n"); return true; } @@ -386,7 +386,7 @@ static bool test_LookupNames3(struct dcerpc_pipe *p, NTSTATUS status; int i; - printf("\nTesting LookupNames3 with %d names\n", tnames->count); + torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count); sids.count = 0; sids.sids = NULL; @@ -410,7 +410,7 @@ static bool test_LookupNames3(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupNames3(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("LookupNames3 failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "LookupNames3 failed - %s\n", nt_errstr(status)); return false; } @@ -422,7 +422,7 @@ static bool test_LookupNames3(struct dcerpc_pipe *p, } } - printf("\n"); + torture_comment(tctx, "\n"); return true; } @@ -440,7 +440,7 @@ static bool test_LookupNames4(struct dcerpc_pipe *p, NTSTATUS status; int i; - printf("\nTesting LookupNames4 with %d names\n", tnames->count); + torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count); sids.count = 0; sids.sids = NULL; @@ -463,7 +463,7 @@ static bool test_LookupNames4(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupNames4(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("LookupNames4 failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "LookupNames4 failed - %s\n", nt_errstr(status)); return false; } @@ -475,7 +475,7 @@ static bool test_LookupNames4(struct dcerpc_pipe *p, } } - printf("\n"); + torture_comment(tctx, "\n"); return true; } @@ -492,7 +492,7 @@ static bool test_LookupSids(struct dcerpc_pipe *p, uint32_t count = sids->num_sids; NTSTATUS status; - printf("\nTesting LookupSids\n"); + torture_comment(tctx, "\nTesting LookupSids\n"); names.count = 0; names.names = NULL; @@ -508,11 +508,11 @@ static bool test_LookupSids(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupSids(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("LookupSids failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status)); return false; } - printf("\n"); + torture_comment(tctx, "\n"); if (!test_LookupNames(p, tctx, handle, &names)) { return false; @@ -533,7 +533,7 @@ static bool test_LookupSids2(struct dcerpc_pipe *p, uint32_t count = sids->num_sids; NTSTATUS status; - printf("\nTesting LookupSids2\n"); + torture_comment(tctx, "\nTesting LookupSids2\n"); names.count = 0; names.names = NULL; @@ -551,11 +551,11 @@ static bool test_LookupSids2(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupSids2(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("LookupSids2 failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "LookupSids2 failed - %s\n", nt_errstr(status)); return false; } - printf("\n"); + torture_comment(tctx, "\n"); if (!test_LookupNames2(p, tctx, handle, &names, false)) { return false; @@ -578,7 +578,7 @@ static bool test_LookupSids3(struct dcerpc_pipe *p, uint32_t count = sids->num_sids; NTSTATUS status; - printf("\nTesting LookupSids3\n"); + torture_comment(tctx, "\nTesting LookupSids3\n"); names.count = 0; names.names = NULL; @@ -597,15 +597,15 @@ static bool test_LookupSids3(struct dcerpc_pipe *p, if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) { - printf("not considering %s to be an error\n", nt_errstr(status)); + torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status)); return true; } - printf("LookupSids3 failed - %s - not considered an error\n", + torture_comment(tctx, "LookupSids3 failed - %s - not considered an error\n", nt_errstr(status)); return false; } - printf("\n"); + torture_comment(tctx, "\n"); if (!test_LookupNames4(p, tctx, &names, false)) { return false; @@ -623,7 +623,7 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, struct lsa_SidArray sids; int i; - printf("\nTesting LookupSids with lots of SIDs\n"); + torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n"); sids.num_sids = 100; @@ -654,11 +654,11 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupSids(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("LookupSids failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status)); return false; } - printf("\n"); + torture_comment(tctx, "\n"); if (!test_LookupNames(p, tctx, handle, &names)) { return false; @@ -672,7 +672,7 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, names.count = 0; names.names = NULL; - printf("\nTesting LookupSids3\n"); + torture_comment(tctx, "\nTesting LookupSids3\n"); r.in.sids = &sids; r.in.names = &names; @@ -688,10 +688,10 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) { - printf("not considering %s to be an error\n", nt_errstr(status)); + torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status)); return true; } - printf("LookupSids3 failed - %s\n", + torture_comment(tctx, "LookupSids3 failed - %s\n", nt_errstr(status)); return false; } @@ -700,7 +700,7 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, } } - printf("\n"); + torture_comment(tctx, "\n"); @@ -742,7 +742,7 @@ static bool test_LookupSids_async(struct dcerpc_pipe *p, names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests); r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests); - printf("\nTesting %d async lookupsids request\n", num_async_requests); + torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests); req = talloc_array(tctx, struct rpc_request *, num_async_requests); @@ -804,7 +804,7 @@ static bool test_LookupPrivValue(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupPrivValue(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("\nLookupPrivValue failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "\nLookupPrivValue failed - %s\n", nt_errstr(status)); return false; } @@ -826,7 +826,7 @@ static bool test_LookupPrivName(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupPrivName(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("\nLookupPrivName failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status)); return false; } @@ -844,7 +844,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, struct lsa_PrivilegeSet privs; bool ret = true; - printf("\nTesting RemovePrivilegesFromAccount\n"); + torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n"); r.in.handle = acct_handle; r.in.remove_all = 0; @@ -868,7 +868,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupPrivName(p, tctx, &r_name); if (!NT_STATUS_IS_OK(status)) { - printf("\nLookupPrivName failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status)); return false; } /* Windows 2008 does not allow this to be removed */ @@ -876,7 +876,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, return ret; } - printf("RemovePrivilegesFromAccount failed to remove %s - %s\n", + torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n", name->string, nt_errstr(status)); return false; @@ -895,7 +895,7 @@ static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p, struct lsa_PrivilegeSet privs; bool ret = true; - printf("\nTesting AddPrivilegesToAccount\n"); + torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n"); r.in.handle = acct_handle; r.in.privs = &privs; @@ -908,7 +908,7 @@ static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p, status = dcerpc_lsa_AddPrivilegesToAccount(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("AddPrivilegesToAccount failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "AddPrivilegesToAccount failed - %s\n", nt_errstr(status)); return false; } @@ -925,14 +925,14 @@ static bool test_EnumPrivsAccount(struct dcerpc_pipe *p, struct lsa_PrivilegeSet *privs = NULL; bool ret = true; - printf("\nTesting EnumPrivsAccount\n"); + torture_comment(tctx, "\nTesting EnumPrivsAccount\n"); r.in.handle = acct_handle; r.out.privs = &privs; status = dcerpc_lsa_EnumPrivsAccount(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("EnumPrivsAccount failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "EnumPrivsAccount failed - %s\n", nt_errstr(status)); return false; } @@ -961,46 +961,46 @@ static bool test_GetSystemAccessAccount(struct dcerpc_pipe *p, uint32_t access_mask; struct lsa_GetSystemAccessAccount r; - printf("\nTesting GetSystemAccessAccount\n"); + torture_comment(tctx, "\nTesting GetSystemAccessAccount\n"); r.in.handle = acct_handle; r.out.access_mask = &access_mask; status = dcerpc_lsa_GetSystemAccessAccount(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("GetSystemAccessAccount failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "GetSystemAccessAccount failed - %s\n", nt_errstr(status)); return false; } if (r.out.access_mask != NULL) { - printf("Rights:"); + torture_comment(tctx, "Rights:"); if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE) - printf(" LSA_POLICY_MODE_INTERACTIVE"); + torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE"); if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK) - printf(" LSA_POLICY_MODE_NETWORK"); + torture_comment(tctx, " LSA_POLICY_MODE_NETWORK"); if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH) - printf(" LSA_POLICY_MODE_BATCH"); + torture_comment(tctx, " LSA_POLICY_MODE_BATCH"); if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE) - printf(" LSA_POLICY_MODE_SERVICE"); + torture_comment(tctx, " LSA_POLICY_MODE_SERVICE"); if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY) - printf(" LSA_POLICY_MODE_PROXY"); + torture_comment(tctx, " LSA_POLICY_MODE_PROXY"); if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE) - printf(" LSA_POLICY_MODE_DENY_INTERACTIVE"); + torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE"); if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK) - printf(" LSA_POLICY_MODE_DENY_NETWORK"); + torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK"); if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH) - printf(" LSA_POLICY_MODE_DENY_BATCH"); + torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH"); if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE) - printf(" LSA_POLICY_MODE_DENY_SERVICE"); + torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE"); if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE) - printf(" LSA_POLICY_MODE_REMOTE_INTERACTIVE"); + torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE"); if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE) - printf(" LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE"); + torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE"); if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL) - printf(" LSA_POLICY_MODE_ALL"); + torture_comment(tctx, " LSA_POLICY_MODE_ALL"); if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4) - printf(" LSA_POLICY_MODE_ALL_NT4"); - printf("\n"); + torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4"); + torture_comment(tctx, "\n"); } return true; @@ -1013,12 +1013,12 @@ static bool test_Delete(struct dcerpc_pipe *p, NTSTATUS status; struct lsa_Delete r; - printf("\nTesting Delete\n"); + torture_comment(tctx, "\nTesting Delete\n"); r.in.handle = handle; status = dcerpc_lsa_Delete(p, tctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { - printf("Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status)); + torture_comment(tctx, "Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status)); return false; } @@ -1032,13 +1032,13 @@ static bool test_DeleteObject(struct dcerpc_pipe *p, NTSTATUS status; struct lsa_DeleteObject r; - printf("\nTesting DeleteObject\n"); + torture_comment(tctx, "\nTesting DeleteObject\n"); r.in.handle = handle; r.out.handle = handle; status = dcerpc_lsa_DeleteObject(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("DeleteObject failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "DeleteObject failed - %s\n", nt_errstr(status)); return false; } @@ -1057,7 +1057,7 @@ static bool test_CreateAccount(struct dcerpc_pipe *p, newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854"); - printf("\nTesting CreateAccount\n"); + torture_comment(tctx, "\nTesting CreateAccount\n"); r.in.handle = handle; r.in.sid = newsid; @@ -1074,11 +1074,11 @@ static bool test_CreateAccount(struct dcerpc_pipe *p, status = dcerpc_lsa_OpenAccount(p, tctx, &r_o); if (!NT_STATUS_IS_OK(status)) { - printf("OpenAccount failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status)); return false; } } else if (!NT_STATUS_IS_OK(status)) { - printf("CreateAccount failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "CreateAccount failed - %s\n", nt_errstr(status)); return false; } @@ -1109,7 +1109,7 @@ static bool test_DeleteTrustedDomain(struct dcerpc_pipe *p, status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status)); return false; } @@ -1137,7 +1137,7 @@ static bool test_DeleteTrustedDomainBySid(struct dcerpc_pipe *p, status = dcerpc_lsa_DeleteTrustedDomain(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("DeleteTrustedDomain failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "DeleteTrustedDomain failed - %s\n", nt_errstr(status)); return false; } @@ -1183,7 +1183,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (uint_t)random()); for (i=0; i< 2; i++) { - printf("\nTesting CreateSecret of %s\n", secname[i]); + torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]); init_lsa_String(&r.in.name, secname[i]); @@ -1193,7 +1193,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, status = dcerpc_lsa_CreateSecret(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("CreateSecret failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "CreateSecret failed - %s\n", nt_errstr(status)); return false; } @@ -1203,7 +1203,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, status = dcerpc_lsa_CreateSecret(p, tctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { - printf("CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status)); + torture_comment(tctx, "CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status)); return false; } @@ -1212,17 +1212,17 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, r2.in.name = r.in.name; r2.out.sec_handle = &sec_handle2; - printf("Testing OpenSecret\n"); + torture_comment(tctx, "Testing OpenSecret\n"); status = dcerpc_lsa_OpenSecret(p, tctx, &r2); if (!NT_STATUS_IS_OK(status)) { - printf("OpenSecret failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "OpenSecret failed - %s\n", nt_errstr(status)); return false; } status = dcerpc_fetch_session_key(p, &session_key); if (!NT_STATUS_IS_OK(status)) { - printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status)); return false; } @@ -1235,11 +1235,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, r3.in.new_val->length = enc_key.length; r3.in.new_val->size = enc_key.length; - printf("Testing SetSecret\n"); + torture_comment(tctx, "Testing SetSecret\n"); status = dcerpc_lsa_SetSecret(p, tctx, &r3); if (!NT_STATUS_IS_OK(status)) { - printf("SetSecret failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status)); return false; } @@ -1253,11 +1253,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, /* break the encrypted data */ enc_key.data[0]++; - printf("Testing SetSecret with broken key\n"); + torture_comment(tctx, "Testing SetSecret with broken key\n"); status = dcerpc_lsa_SetSecret(p, tctx, &r3); if (!NT_STATUS_EQUAL(status, NT_STATUS_UNKNOWN_REVISION)) { - printf("SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status)); + torture_comment(tctx, "SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status)); ret = false; } @@ -1275,14 +1275,14 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, bufp1.buf = NULL; - printf("Testing QuerySecret\n"); + torture_comment(tctx, "Testing QuerySecret\n"); status = dcerpc_lsa_QuerySecret(p, tctx, &r4); if (!NT_STATUS_IS_OK(status)) { - printf("QuerySecret failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status)); ret = false; } else { if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) { - printf("No secret buffer returned\n"); + torture_comment(tctx, "No secret buffer returned\n"); ret = false; } else { blob1.data = r4.out.new_val->buf->data; @@ -1294,7 +1294,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, &blob1, &session_key); if (strcmp(secret1, secret2) != 0) { - printf("Returned secret (r4) '%s' doesn't match '%s'\n", + torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n", secret2, secret1); ret = false; } @@ -1312,11 +1312,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, msleep(200); - printf("Testing SetSecret (existing value should move to old)\n"); + torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n"); status = dcerpc_lsa_SetSecret(p, tctx, &r5); if (!NT_STATUS_IS_OK(status)) { - printf("SetSecret failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status)); ret = false; } @@ -1337,14 +1337,14 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, status = dcerpc_lsa_QuerySecret(p, tctx, &r6); if (!NT_STATUS_IS_OK(status)) { - printf("QuerySecret failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status)); ret = false; secret4 = NULL; } else { if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) { - printf("Both secret buffers and both times not returned\n"); + torture_comment(tctx, "Both secret buffers and both times not returned\n"); ret = false; secret4 = NULL; } else { @@ -1357,7 +1357,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, &blob1, &session_key); if (strcmp(secret3, secret4) != 0) { - printf("Returned NEW secret %s doesn't match %s\n", secret4, secret3); + torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3); ret = false; } @@ -1370,12 +1370,12 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, &blob1, &session_key); if (strcmp(secret1, secret2) != 0) { - printf("Returned OLD secret %s doesn't match %s\n", secret2, secret1); + torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1); ret = false; } if (*r6.out.new_mtime == *r6.out.old_mtime) { - printf("Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n", + torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n", i, secname[i], nt_time_string(tctx, *r6.out.old_mtime), @@ -1394,11 +1394,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, r7.in.old_val->size = enc_key.length; r7.in.new_val = NULL; - printf("Testing SetSecret of old Secret only\n"); + torture_comment(tctx, "Testing SetSecret of old Secret only\n"); status = dcerpc_lsa_SetSecret(p, tctx, &r7); if (!NT_STATUS_IS_OK(status)) { - printf("SetSecret failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status)); ret = false; } @@ -1416,20 +1416,20 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, status = dcerpc_lsa_QuerySecret(p, tctx, &r8); if (!NT_STATUS_IS_OK(status)) { - printf("QuerySecret failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status)); ret = false; } else { if (!r8.out.new_val || !r8.out.old_val) { - printf("in/out pointers not returned, despite being set on in for QuerySecret\n"); + torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n"); ret = false; } else if (r8.out.new_val->buf != NULL) { - printf("NEW secret buffer must not be returned after OLD set\n"); + torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n"); ret = false; } else if (r8.out.old_val->buf == NULL) { - printf("OLD secret buffer was not returned after OLD set\n"); + torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n"); ret = false; } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) { - printf("Both times not returned after OLD set\n"); + torture_comment(tctx, "Both times not returned after OLD set\n"); ret = false; } else { blob1.data = r8.out.old_val->buf->data; @@ -1441,12 +1441,12 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, &blob1, &session_key); if (strcmp(secret5, secret6) != 0) { - printf("Returned OLD secret %s doesn't match %s\n", secret5, secret6); + torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6); ret = false; } if (*r8.out.new_mtime != *r8.out.old_mtime) { - printf("Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n", + torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n", secname[i], nt_time_string(tctx, *r8.out.old_mtime), nt_time_string(tctx, *r8.out.new_mtime)); @@ -1467,15 +1467,15 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, d_o.out.handle = &sec_handle2; status = dcerpc_lsa_DeleteObject(p, tctx, &d_o); if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { - printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status)); + torture_comment(tctx, "Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status)); ret = false; } else { - printf("Testing OpenSecret of just-deleted secret\n"); + torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n"); status = dcerpc_lsa_OpenSecret(p, tctx, &r2); if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - printf("OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status)); + torture_comment(tctx, "OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status)); ret = false; } } @@ -1495,7 +1495,7 @@ static bool test_EnumAccountRights(struct dcerpc_pipe *p, struct lsa_EnumAccountRights r; struct lsa_RightSet rights; - printf("\nTesting EnumAccountRights\n"); + torture_comment(tctx, "\nTesting EnumAccountRights\n"); r.in.handle = acct_handle; r.in.sid = sid; @@ -1503,7 +1503,7 @@ static bool test_EnumAccountRights(struct dcerpc_pipe *p, status = dcerpc_lsa_EnumAccountRights(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("EnumAccountRights of %s failed - %s\n", + torture_comment(tctx, "EnumAccountRights of %s failed - %s\n", dom_sid_string(tctx, sid), nt_errstr(status)); return false; } @@ -1522,11 +1522,11 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p, struct sec_desc_buf *sdbuf = NULL; if (torture_setting_bool(tctx, "samba4", false)) { - printf("\nskipping QuerySecurity test against Samba4\n"); + torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n"); return true; } - printf("\nTesting QuerySecurity\n"); + torture_comment(tctx, "\nTesting QuerySecurity\n"); r.in.handle = acct_handle; r.in.sec_info = 7; @@ -1534,7 +1534,7 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p, status = dcerpc_lsa_QuerySecurity(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("QuerySecurity failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(status)); return false; } @@ -1550,7 +1550,7 @@ static bool test_OpenAccount(struct dcerpc_pipe *p, struct lsa_OpenAccount r; struct policy_handle acct_handle; - printf("\nTesting OpenAccount\n"); + torture_comment(tctx, "\nTesting OpenAccount\n"); r.in.handle = handle; r.in.sid = sid; @@ -1559,7 +1559,7 @@ static bool test_OpenAccount(struct dcerpc_pipe *p, status = dcerpc_lsa_OpenAccount(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("OpenAccount failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status)); return false; } @@ -1589,7 +1589,7 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p, int i; bool ret = true; - printf("\nTesting EnumAccounts\n"); + torture_comment(tctx, "\nTesting EnumAccounts\n"); r.in.handle = handle; r.in.resume_handle = &resume_handle; @@ -1604,7 +1604,7 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p, break; } if (!NT_STATUS_IS_OK(status)) { - printf("EnumAccounts failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status)); return false; } @@ -1620,31 +1620,31 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p, * be on schannel, or we would not be able to do the * rest */ - printf("Testing all accounts\n"); + torture_comment(tctx, "Testing all accounts\n"); for (i=0;istring); + torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string); r.in.handle = handle; r.in.name = priv_name; @@ -1675,10 +1675,10 @@ static bool test_LookupPrivDisplayName(struct dcerpc_pipe *p, status = dcerpc_lsa_LookupPrivDisplayName(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(status)); return false; } - printf("%s -> \"%s\" (language 0x%x/0x%x)\n", + torture_comment(tctx, "%s -> \"%s\" (language 0x%x/0x%x)\n", priv_name->string, disp_name->string, r.in.language_id, *r.out.returned_language_id); @@ -1696,7 +1696,7 @@ static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, ZERO_STRUCT(sids); - printf("\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string); + torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string); r.in.handle = handle; r.in.name = priv_name; @@ -1710,7 +1710,7 @@ static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, } if (!NT_STATUS_IS_OK(status)) { - printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(status)); return false; } @@ -1729,7 +1729,7 @@ static bool test_EnumPrivs(struct dcerpc_pipe *p, int i; bool ret = true; - printf("\nTesting EnumPrivs\n"); + torture_comment(tctx, "\nTesting EnumPrivs\n"); r.in.handle = handle; r.in.resume_handle = &resume_handle; @@ -1740,7 +1740,7 @@ static bool test_EnumPrivs(struct dcerpc_pipe *p, resume_handle = 0; status = dcerpc_lsa_EnumPrivs(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("EnumPrivs failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "EnumPrivs failed - %s\n", nt_errstr(status)); return false; } @@ -1766,10 +1766,10 @@ static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p, struct lsa_String string; struct lsa_ForestTrustInformation info, *info_ptr; - printf("\nTesting lsaRQueryForestTrustInformation\n"); + torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n"); if (torture_setting_bool(tctx, "samba4", false)) { - printf("skipping QueryForestTrustInformation against Samba4\n"); + torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n"); return true; } @@ -1789,7 +1789,7 @@ static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p, status = dcerpc_lsa_lsaRQueryForestTrustInformation(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status)); + torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status)); ret = false; } @@ -1824,7 +1824,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, int i,j; bool ret = true; - printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n"); + torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n"); for (i=0; i< domains->count; i++) { struct lsa_OpenTrustedDomain trust; struct lsa_OpenTrustedDomainByName trust_by_name; @@ -1844,7 +1844,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, status = dcerpc_lsa_OpenTrustedDomain(p, tctx, &trust); if (!NT_STATUS_IS_OK(status)) { - printf("OpenTrustedDomain failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(status)); return false; } @@ -1862,11 +1862,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, q.out.info = &info; status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status) && ok[j]) { - printf("QueryTrustedDomainInfo level %d failed - %s\n", + torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", levels[j], nt_errstr(status)); ret = false; } else if (NT_STATUS_IS_OK(status) && !ok[j]) { - printf("QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n", + torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n", levels[j], nt_errstr(status)); ret = false; } @@ -1874,7 +1874,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, status = dcerpc_lsa_CloseTrustedDomainEx(p, tctx, &c_trust); if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { - printf("Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status)); + torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status)); return false; } @@ -1883,7 +1883,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, status = dcerpc_lsa_Close(p, tctx, &c); if (!NT_STATUS_IS_OK(status)) { - printf("Close of trusted domain failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status)); return false; } @@ -1902,11 +1902,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, tctx, &q); if (!NT_STATUS_IS_OK(status) && ok[j]) { - printf("QueryTrustedDomainInfoBySid level %d failed - %s\n", + torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n", levels[j], nt_errstr(status)); ret = false; } else if (NT_STATUS_IS_OK(status) && !ok[j]) { - printf("QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n", + torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n", levels[j], nt_errstr(status)); ret = false; } @@ -1921,7 +1921,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &trust_by_name); if (!NT_STATUS_IS_OK(status)) { - printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status)); return false; } @@ -1933,11 +1933,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, q.out.info = &info; status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status) && ok[j]) { - printf("QueryTrustedDomainInfo level %d failed - %s\n", + torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", levels[j], nt_errstr(status)); ret = false; } else if (NT_STATUS_IS_OK(status) && !ok[j]) { - printf("QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n", + torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n", levels[j], nt_errstr(status)); ret = false; } @@ -1948,7 +1948,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, status = dcerpc_lsa_Close(p, tctx, &c); if (!NT_STATUS_IS_OK(status)) { - printf("Close of trusted domain failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status)); return false; } @@ -1965,11 +1965,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, q.out.info = &info; status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, tctx, &q); if (!NT_STATUS_IS_OK(status) && ok[j]) { - printf("QueryTrustedDomainInfoByName level %d failed - %s\n", + torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n", levels[j], nt_errstr(status)); ret = false; } else if (NT_STATUS_IS_OK(status) && !ok[j]) { - printf("QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n", + torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n", levels[j], nt_errstr(status)); ret = false; } @@ -1990,7 +1990,7 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, struct lsa_DomainListEx domains_ex; bool ret = true; - printf("\nTesting EnumTrustDom\n"); + torture_comment(tctx, "\nTesting EnumTrustDom\n"); r.in.handle = handle; r.in.resume_handle = &resume_handle; @@ -2002,11 +2002,11 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, if (NT_STATUS_IS_OK(enum_status)) { if (domains.count == 0) { - printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); + torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); return false; } } else if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) { - printf("EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status)); + torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status)); return false; } @@ -2027,24 +2027,24 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, if (domains.count == 0) { return true; } - printf("EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); + torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); return false; } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) { /* Windows 2003 gets this off by one on the first run */ if (r.out.domains->count < 3 || r.out.domains->count > 4) { - printf("EnumTrustDom didn't fill the buffer we " + torture_comment(tctx, "EnumTrustDom didn't fill the buffer we " "asked it to (got %d, expected %d / %d == %d entries)\n", r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size); ret = false; } } else if (!NT_STATUS_IS_OK(enum_status)) { - printf("EnumTrustDom failed - %s\n", nt_errstr(enum_status)); + torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(enum_status)); return false; } if (domains.count == 0) { - printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); + torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); return false; } @@ -2052,7 +2052,7 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, } while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES))); - printf("\nTesting EnumTrustedDomainsEx\n"); + torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n"); r_ex.in.handle = handle; r_ex.in.resume_handle = &resume_handle; @@ -2063,7 +2063,7 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, enum_status = dcerpc_lsa_EnumTrustedDomainsEx(p, tctx, &r_ex); if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) { - printf("EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status)); + torture_comment(tctx, "EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status)); return false; } @@ -2082,12 +2082,12 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, if (domains_ex.count == 0) { return true; } - printf("EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); + torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); return false; } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) { /* Windows 2003 gets this off by one on the first run */ if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) { - printf("EnumTrustDom didn't fill the buffer we " + torture_comment(tctx, "EnumTrustDom didn't fill the buffer we " "asked it to (got %d, expected %d / %d == %d entries)\n", r_ex.out.domains->count, r_ex.in.max_size, @@ -2095,12 +2095,12 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER); } } else if (!NT_STATUS_IS_OK(enum_status)) { - printf("EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status)); + torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status)); return false; } if (domains_ex.count == 0) { - printf("EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); + torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); return false; } @@ -2125,7 +2125,7 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, union lsa_TrustedDomainInfo *info = NULL; int i; - printf("\nTesting CreateTrustedDomain for 12 domains\n"); + torture_comment(tctx, "\nTesting CreateTrustedDomain for 12 domains\n"); if (!test_EnumTrustDom(p, tctx, handle)) { ret = false; @@ -2151,7 +2151,7 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, status = dcerpc_lsa_CreateTrustedDomain(p, tctx, &r); } if (!NT_STATUS_IS_OK(status)) { - printf("CreateTrustedDomain failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(status)); ret = false; } else { @@ -2160,28 +2160,28 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, q.out.info = &info; status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status)) { - printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); ret = false; } else if (!q.out.info) { ret = false; } else { if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) { - printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n", + torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n", info->info_ex.netbios_name.string, trustinfo.name.string); ret = false; } if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) { - printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n", + torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n", trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL); ret = false; } if (info->info_ex.trust_attributes != 0) { - printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n", + torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n", trust_name, info->info_ex.trust_attributes, 0); ret = false; } if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) { - printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n", + torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n", trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND); ret = false; } @@ -2222,11 +2222,11 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, enum ndr_err_code ndr_err; int i; - printf("\nTesting CreateTrustedDomainEx2 for 12 domains\n"); + torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for 12 domains\n"); status = dcerpc_fetch_session_key(p, &session_key); if (!NT_STATUS_IS_OK(status)) { - printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status)); return false; } @@ -2263,7 +2263,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, ndr_err = ndr_push_struct_blob(&auth_blob, tctx, lp_iconv_convenience(tctx->lp_ctx), &auth_struct, (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - printf("ndr_push_struct_blob of trustDomainPasswords structure failed"); + torture_comment(tctx, "ndr_push_struct_blob of trustDomainPasswords structure failed"); ret = false; } @@ -2284,7 +2284,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, status = dcerpc_lsa_CreateTrustedDomainEx2(p, tctx, &r); } if (!NT_STATUS_IS_OK(status)) { - printf("CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status)); + torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status)); ret = false; } else { @@ -2293,29 +2293,29 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, q.out.info = &info; status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status)) { - printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); ret = false; } else if (!q.out.info) { - printf("QueryTrustedDomainInfo level 1 failed to return an info pointer\n"); + torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n"); ret = false; } else { if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) { - printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n", + torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n", info->info_ex.netbios_name.string, trustinfo.netbios_name.string); ret = false; } if (info->info_ex.trust_type != trustinfo.trust_type) { - printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n", + torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n", trust_name, info->info_ex.trust_type, trustinfo.trust_type); ret = false; } if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) { - printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n", + torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n", trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION); ret = false; } if (info->info_ex.trust_direction != trustinfo.trust_direction) { - printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n", + torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n", trust_name, info->info_ex.trust_direction, trustinfo.trust_direction); ret = false; } @@ -2325,13 +2325,13 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, /* now that we have some domains to look over, we can test the enum calls */ if (!test_EnumTrustDom(p, tctx, handle)) { - printf("test_EnumTrustDom failed\n"); + torture_comment(tctx, "test_EnumTrustDom failed\n"); ret = false; } for (i=0; i<12; i++) { if (!test_DeleteTrustedDomainBySid(p, tctx, handle, domsid[i])) { - printf("test_DeleteTrustedDomainBySid failed\n"); + torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n"); ret = false; } } @@ -2349,14 +2349,14 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p, int i; bool ret = true; - printf("\nTesting QueryDomainInformationPolicy\n"); + torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n"); for (i=2;i<4;i++) { r.in.handle = handle; r.in.level = i; r.out.info = &info; - printf("\nTrying QueryDomainInformationPolicy level %d\n", i); + torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i); status = dcerpc_lsa_QueryDomainInformationPolicy(p, tctx, &r); @@ -2364,7 +2364,7 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p, if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { continue; } else if (!NT_STATUS_IS_OK(status)) { - printf("QueryDomainInformationPolicy failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(status)); ret = false; continue; } @@ -2386,9 +2386,9 @@ static bool test_QueryInfoPolicyCalls( bool version2, bool ret = true; if (version2) - printf("\nTesting QueryInfoPolicy2\n"); + torture_comment(tctx, "\nTesting QueryInfoPolicy2\n"); else - printf("\nTesting QueryInfoPolicy\n"); + torture_comment(tctx, "\nTesting QueryInfoPolicy\n"); for (i=1;i<=14;i++) { r.in.handle = handle; @@ -2396,9 +2396,9 @@ static bool test_QueryInfoPolicyCalls( bool version2, r.out.info = &info; if (version2) - printf("\nTrying QueryInfoPolicy2 level %d\n", i); + torture_comment(tctx, "\nTrying QueryInfoPolicy2 level %d\n", i); else - printf("\nTrying QueryInfoPolicy level %d\n", i); + torture_comment(tctx, "\nTrying QueryInfoPolicy level %d\n", i); if (version2) /* We can perform the cast, because both types are @@ -2413,7 +2413,7 @@ static bool test_QueryInfoPolicyCalls( bool version2, case LSA_POLICY_INFO_AUDIT_FULL_SET: case LSA_POLICY_INFO_AUDIT_FULL_QUERY: if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { - printf("Server should have failed level %u: %s\n", i, nt_errstr(status)); + torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(status)); ret = false; } break; @@ -2430,9 +2430,9 @@ static bool test_QueryInfoPolicyCalls( bool version2, case LSA_POLICY_INFO_PD: if (!NT_STATUS_IS_OK(status)) { if (version2) - printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); else - printf("QueryInfoPolicy failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status)); ret = false; } break; @@ -2441,16 +2441,16 @@ static bool test_QueryInfoPolicyCalls( bool version2, /* Other levels not implemented yet */ if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) { if (version2) - printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); else - printf("QueryInfoPolicy failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status)); ret = false; } } else if (!NT_STATUS_IS_OK(status)) { if (version2) - printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); else - printf("QueryInfoPolicy failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status)); ret = false; } break; @@ -2522,7 +2522,7 @@ static bool test_GetUserName(struct dcerpc_pipe *p, struct lsa_String *authority_name_p = NULL; struct lsa_String *account_name_p = NULL; - printf("\nTesting GetUserName\n"); + torture_comment(tctx, "\nTesting GetUserName\n"); r.in.system_name = "\\"; r.in.account_name = &account_name_p; @@ -2532,7 +2532,7 @@ static bool test_GetUserName(struct dcerpc_pipe *p, status = dcerpc_lsa_GetUserName(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("GetUserName failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status)); ret = false; } @@ -2544,7 +2544,7 @@ static bool test_GetUserName(struct dcerpc_pipe *p, status = dcerpc_lsa_GetUserName(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("GetUserName failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status)); ret = false; } @@ -2559,25 +2559,25 @@ bool test_lsa_Close(struct dcerpc_pipe *p, struct lsa_Close r; struct policy_handle handle2; - printf("\nTesting Close\n"); + torture_comment(tctx, "\nTesting Close\n"); r.in.handle = handle; r.out.handle = &handle2; status = dcerpc_lsa_Close(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("Close failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "Close failed - %s\n", nt_errstr(status)); return false; } status = dcerpc_lsa_Close(p, tctx, &r); /* its really a fault - we need a status code for rpc fault */ if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { - printf("Close failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "Close failed - %s\n", nt_errstr(status)); return false; } - printf("\n"); + torture_comment(tctx, "\n"); return true; } -- cgit From c9fe3256d87f4fcd119dc1a3c784f2196b4ad2fd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2009 10:51:34 +0200 Subject: s4:heimdal_build: tell heimdal we have inet_aton() This should fix problems on Solaris. metze --- source4/heimdal_build/roken.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/heimdal_build/roken.h b/source4/heimdal_build/roken.h index decce03522..87060cff17 100644 --- a/source4/heimdal_build/roken.h +++ b/source4/heimdal_build/roken.h @@ -97,6 +97,10 @@ #define HAVE_INNETGR #endif +#ifndef HAVE_INET_ATON +#define HAVE_INET_ATON +#endif + /* we lie about having pidfile() so that NetBSD5 can compile. Nothing in the parts of heimdal we use actually uses pidfile(), and we don't use it in Samba, so this works, although its ugly */ -- cgit From 39684d2cbe1c8c69dc9ca5c6e05861e24091bb83 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2009 09:06:42 +0200 Subject: tevent: try to fix the build on QNX qnx18 6.4.1 it doesn't have SA_RESTART defined metze --- lib/tevent/testsuite.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c index d964fb33d3..f9aca91aa1 100644 --- a/lib/tevent/testsuite.c +++ b/lib/tevent/testsuite.c @@ -66,7 +66,13 @@ static bool test_event_context(struct torture_context *test, const char *backend = (const char *)test_data; int alarm_count=0, info_count=0; struct tevent_fd *fde; - struct signal_event *se1, *se2, *se3; +#ifdef SA_RESTART + struct tevent_signal *se1 = NULL; +#endif + struct tevent_signal *se2 = NULL; +#ifdef SA_SIGINFO + struct tevent_signal *se3 = NULL; +#endif int finished=0; struct timeval t; char c = 0; @@ -92,7 +98,9 @@ static bool test_event_context(struct torture_context *test, event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(2,0), finished_handler, &finished); +#ifdef SA_RESTART se1 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESTART, count_handler, &alarm_count); +#endif se2 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESETHAND, count_handler, &alarm_count); #ifdef SA_SIGINFO se3 = event_add_signal(ev_ctx, ev_ctx, SIGUSR1, SA_SIGINFO, count_handler, &info_count); @@ -120,7 +128,9 @@ static bool test_event_context(struct torture_context *test, torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t)); +#ifdef SA_RESTART talloc_free(se1); +#endif torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch"); -- cgit From 98aba452fbddb9f05250a7e4dc8979990759f671 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2009 12:08:56 +0200 Subject: s4:heimdal_build: try to fix the build on systems without ifaddrs.h metze --- source4/heimdal_build/ifaddrs.hin | 1 + source4/heimdal_build/internal.m4 | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 source4/heimdal_build/ifaddrs.hin diff --git a/source4/heimdal_build/ifaddrs.hin b/source4/heimdal_build/ifaddrs.hin new file mode 100644 index 0000000000..a50b03335b --- /dev/null +++ b/source4/heimdal_build/ifaddrs.hin @@ -0,0 +1 @@ +#include "system/network.h" diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index 5c8d78e56d..e7e7ae1842 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -46,6 +46,15 @@ dnl declarations will be correct). Phew! AC_CHECK_HEADERS([err.h], [], [ cp heimdal/lib/roken/err.hin heimdal_build/err.h ]) +dnl Not all systems have ifaddrs.h, so we provide a replacement. Heimdal +dnl unconditionally #includes , so we need to create an ifaddrs.h, +dnl but we can't just have a static one because we don't want to use +dnl it on systems that have a real ifaddrs.h. If the system has a real +dnl ifaddrs.h. We don't use heimdal's lib/roken/ifaddrs.hin because +dnl our libreplace would conflict with it. +AC_CHECK_HEADERS([ifaddrs.h], [], + [ cp heimdal_build/ifaddrs.hin heimdal_build/ifaddrs.h ]) + AC_CHECK_HEADERS([ \ crypt.h \ curses.h \ -- cgit From 4a754d029b0eb229b23980aa4a80dae2b485a302 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2009 12:21:29 +0200 Subject: s4:heimdal_build: predefine GSSAPI_DEPRECATED depending on the compiler version Otherwise heimdal/lib/gssapi/gssapi/gssapi.h will just define it to __attribute__ ((deprecated)) which is not supported by all compilers we care about. This should fix the build on Tru64 metze --- source4/heimdal_build/krb5-types.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/heimdal_build/krb5-types.h b/source4/heimdal_build/krb5-types.h index cdc5a3cba9..94973d7fbe 100644 --- a/source4/heimdal_build/krb5-types.h +++ b/source4/heimdal_build/krb5-types.h @@ -10,4 +10,12 @@ typedef socklen_t krb5_socklen_t; typedef ssize_t krb5_ssize_t; +#ifndef GSSAPI_DEPRECATED +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) +#define GSSAPI_DEPRECATED __attribute__ ((deprecated)) +#else +#define GSSAPI_DEPRECATED +#endif +#endif + #endif /* __krb5_types_h__ */ -- cgit From 74c405db406d0971ba4fe2abae4ebd950d27ab1c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 2009 09:54:14 -0700 Subject: Tidyup prompted by #6554 - Wrong deallocation in sam_account_ok. Jeremy. --- source3/auth/auth_sam.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index a2634feb6c..26b45e47e5 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -226,10 +226,10 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx, if (*workstation_list) { bool invalid_ws = True; - char *tok; + char *tok = NULL; const char *s = workstation_list; + char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name); - const char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name); if (machine_name == NULL) return NT_STATUS_NO_MEMORY; @@ -251,6 +251,7 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx, TALLOC_FREE(tok); } TALLOC_FREE(tok); + TALLOC_FREE(machine_name); if (invalid_ws) return NT_STATUS_INVALID_WORKSTATION; -- cgit From 3b899af422075949f3c2f0d14787c7e11a3b16df Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 02:25:43 +0200 Subject: s3-lsa: implement _lsa_EnumAccountsWithUserRight(). Guenther --- source3/rpc_server/srv_lsa_nt.c | 63 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index c62991ee01..f5cfc53840 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -2246,6 +2246,63 @@ NTSTATUS _lsa_LookupPrivValue(pipes_struct *p, return NT_STATUS_OK; } +/*************************************************************************** + _lsa_EnumAccountsWithUserRight + ***************************************************************************/ + +NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, + struct lsa_EnumAccountsWithUserRight *r) +{ + NTSTATUS status; + struct lsa_info *info = NULL; + struct dom_sid *sids = NULL; + int num_sids = 0; + uint32_t i; + SE_PRIV mask; + + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) { + return NT_STATUS_INVALID_HANDLE; + } + + if (info->type != LSA_HANDLE_POLICY_TYPE) { + return NT_STATUS_INVALID_HANDLE; + } + + if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (!r->in.name || !r->in.name->string) { + return NT_STATUS_NO_SUCH_PRIVILEGE; + } + + if (!se_priv_from_name(r->in.name->string, &mask)) { + return NT_STATUS_NO_SUCH_PRIVILEGE; + } + + status = privilege_enum_sids(&mask, p->mem_ctx, + &sids, &num_sids); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + r->out.sids->num_sids = num_sids; + r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr, + r->out.sids->num_sids); + + for (i=0; i < r->out.sids->num_sids; i++) { + r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids, + &sids[i]); + if (!r->out.sids->sids[i].sid) { + TALLOC_FREE(r->out.sids->sids); + r->out.sids->num_sids = 0; + return NT_STATUS_NO_MEMORY; + } + } + + return NT_STATUS_OK; +} + /* * From here on the server routines are just dummy ones to make smbd link with * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are @@ -2318,12 +2375,6 @@ NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccountsWithUserRight *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r) { p->rng_fault_state = True; -- cgit From 35e45fb841e0c36ec2f8b2a8d7216700cc9af691 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 18:32:53 +0200 Subject: s3-lsa: implement _lsa_LookupPrivName(). Guenther --- source3/rpc_server/srv_lsa_nt.c | 51 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index f5cfc53840..1243787503 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1916,6 +1916,51 @@ NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p, return NT_STATUS_OK; } +/*************************************************************************** + _lsa_LookupPrivName + ***************************************************************************/ + +NTSTATUS _lsa_LookupPrivName(pipes_struct *p, + struct lsa_LookupPrivName *r) +{ + struct lsa_info *info = NULL; + const char *name; + struct lsa_StringLarge *lsa_name; + + /* find the connection policy handle. */ + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) { + return NT_STATUS_INVALID_HANDLE; + } + + if (info->type != LSA_HANDLE_POLICY_TYPE) { + return NT_STATUS_INVALID_HANDLE; + } + + if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) { + return NT_STATUS_ACCESS_DENIED; + } + + name = luid_to_privilege_name((LUID *)r->in.luid); + if (!name) { + return NT_STATUS_NO_SUCH_PRIVILEGE; + } + + lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge); + if (!lsa_name) { + return NT_STATUS_NO_MEMORY; + } + + lsa_name->string = talloc_strdup(lsa_name, name); + if (!lsa_name->string) { + TALLOC_FREE(lsa_name); + return NT_STATUS_NO_MEMORY; + } + + *r->out.name = lsa_name; + + return NT_STATUS_OK; +} + /*************************************************************************** _lsa_QuerySecurity ***************************************************************************/ @@ -2369,12 +2414,6 @@ NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r) { p->rng_fault_state = True; -- cgit From 4faef0da762fc1689ae9a3bc657fc6b5e77beb94 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 18:37:19 +0200 Subject: s3-lsa: Fix pointless check for sec_info flags in _lsa_QuerySecurity(). Guenther --- source3/rpc_server/srv_lsa_nt.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 1243787503..1a6d3bae16 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1992,19 +1992,9 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p, return status; } - switch (r->in.sec_info) { - case 1: - /* SD contains only the owner */ - if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) - return NT_STATUS_NO_MEMORY; - break; - case 4: - /* SD contains only the ACL */ - if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) - return NT_STATUS_NO_MEMORY; - break; - default: - return NT_STATUS_INVALID_LEVEL; + *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd); + if (!*r->out.sdbuf) { + return NT_STATUS_NO_MEMORY; } return status; -- cgit From 8d68d04258d8a6e090d2eb27476532d63f741231 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 18:38:25 +0200 Subject: s4-smbtorture: use secinfo flags instead of numbers in lsa test. Guenther --- source4/torture/rpc/lsa.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 7963092cb9..fd7872a968 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -1529,7 +1529,9 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p, torture_comment(tctx, "\nTesting QuerySecurity\n"); r.in.handle = acct_handle; - r.in.sec_info = 7; + r.in.sec_info = SECINFO_OWNER | + SECINFO_GROUP | + SECINFO_DACL; r.out.sdbuf = &sdbuf; status = dcerpc_lsa_QuerySecurity(p, tctx, &r); -- cgit From 106d43a1ddf1a9ad9369bde17acede2a6071fb6c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 18:38:55 +0200 Subject: Revert "fix LSA-TRUSTED-DOMAINS" This reverts commit 3c9b26276083002124674678ac757e859fb6b20e. --- source4/torture/rpc/lsa.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index fd7872a968..dbea8b1768 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -2790,9 +2790,8 @@ struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx) suite = torture_suite_create(mem_ctx, "LSA-TRUSTED-DOMAINS"); - tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "lsa", - &ndr_table_lsarpc, - TEST_MACHINENAME); + tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa", + &ndr_table_lsarpc); torture_rpc_tcase_add_test(tcase, "TrustedDomains", testcase_TrustedDomains); -- cgit From 2e77debc99299cd0defd5c00c6b618dc753905c8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 18:39:06 +0200 Subject: Revert "fix LSA-PRIVILEGES" This reverts commit 0d9fdbceedddb08dbea8ed84e06a218d3ec562f4. --- source4/torture/rpc/lsa.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index dbea8b1768..b45b565452 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -2843,9 +2843,8 @@ struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx) suite = torture_suite_create(mem_ctx, "LSA-PRIVILEGES"); - tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "lsa", - &ndr_table_lsarpc, - TEST_MACHINENAME); + tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa", + &ndr_table_lsarpc); torture_rpc_tcase_add_test(tcase, "Privileges", testcase_Privileges); -- cgit From d7b31ff853ac06d5021314be698109f8487770f9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 16 Jul 2009 12:47:57 +1000 Subject: s4:kdc rename functions from LDB_ to hdb_samba4 The LDB_ prefix is misleading, and stomps on the LDB namespace. This is a Samba4 hdb module, and not something generic. Andrew Bartlett --- source4/kdc/hdb-samba4.c | 142 +++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 21e8c9a38e..25b0deb082 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -154,7 +154,7 @@ static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum h flags.invalid = 1; } -/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in LDB_message2entry() */ +/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in hdb_samba4_message2entry() */ /* if (userAccountControl & UF_MNS_LOGON_ACCOUNT) { @@ -193,7 +193,7 @@ static void hdb_ldb_free_entry(krb5_context context, hdb_entry_ex *entry_ex) talloc_free(entry_ex->ctx); } -static krb5_error_code LDB_message2entry_keys(krb5_context context, +static krb5_error_code hdb_samba4_message2entry_keys(krb5_context context, struct smb_iconv_convenience *iconv_convenience, TALLOC_CTX *mem_ctx, struct ldb_message *msg, @@ -283,22 +283,22 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context, (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { ret = EINVAL; - krb5_set_error_message(context, ret, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob"); - krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob"); + krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: could not parse package_PrimaryKerberosBlob"); + krb5_warnx(context, "hdb_samba4_message2entry_keys: could not parse package_PrimaryKerberosBlob"); goto out; } if (newer_keys && _pkb.version != 4) { ret = EINVAL; - krb5_set_error_message(context, ret, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4"); - krb5_warnx(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4"); + krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4"); + krb5_warnx(context, "hdb_samba4_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4"); goto out; } if (!newer_keys && _pkb.version != 3) { ret = EINVAL; - krb5_set_error_message(context, ret, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3"); - krb5_warnx(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3"); + krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: could not parse Primary:Kerberos not version 3"); + krb5_warnx(context, "hdb_samba4_message2entry_keys: could not parse Primary:Kerberos not version 3"); goto out; } @@ -484,7 +484,7 @@ out: /* * Construct an hdb_entry from a directory entry. */ -static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, +static krb5_error_code hdb_samba4_message2entry(krb5_context context, HDB *db, struct loadparm_context *lp_ctx, TALLOC_CTX *mem_ctx, krb5_const_principal principal, enum hdb_ldb_ent_type ent_type, @@ -511,7 +511,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, if (!samAccountName) { ret = ENOENT; - krb5_set_error_message(context, ret, "LDB_message2entry: no samAccountName present"); + krb5_set_error_message(context, ret, "hdb_samba4_message2entry: no samAccountName present"); goto out; } @@ -690,7 +690,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, entry_ex->entry.generation = NULL; /* Get keys from the db */ - ret = LDB_message2entry_keys(context, p->iconv_convenience, p, msg, userAccountControl, entry_ex); + ret = hdb_samba4_message2entry_keys(context, p->iconv_convenience, p, msg, userAccountControl, entry_ex); if (ret) { /* Could be bougus data in the entry, or out of memory */ goto out; @@ -731,7 +731,7 @@ out: /* * Construct an hdb_entry from a directory entry. */ -static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, +static krb5_error_code hdb_samba4_trust_message2entry(krb5_context context, HDB *db, struct loadparm_context *lp_ctx, TALLOC_CTX *mem_ctx, krb5_const_principal principal, enum trust_direction direction, @@ -909,7 +909,7 @@ out: } -static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx, +static krb5_error_code hdb_samba4_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx, TALLOC_CTX *mem_ctx, const char *realm, struct ldb_dn *realm_dn, @@ -946,39 +946,39 @@ static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context return 0; } -static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode) +static krb5_error_code hdb_samba4_open(krb5_context context, HDB *db, int flags, mode_t mode) { if (db->hdb_master_key_set) { krb5_error_code ret = HDB_ERR_NOENTRY; - krb5_warnx(context, "LDB_open: use of a master key incompatible with LDB\n"); - krb5_set_error_message(context, ret, "LDB_open: use of a master key incompatible with LDB\n"); + krb5_warnx(context, "hdb_samba4_open: use of a master key incompatible with LDB\n"); + krb5_set_error_message(context, ret, "hdb_samba4_open: use of a master key incompatible with LDB\n"); return ret; } return 0; } -static krb5_error_code LDB_close(krb5_context context, HDB *db) +static krb5_error_code hdb_samba4_close(krb5_context context, HDB *db) { return 0; } -static krb5_error_code LDB_lock(krb5_context context, HDB *db, int operation) +static krb5_error_code hdb_samba4_lock(krb5_context context, HDB *db, int operation) { return 0; } -static krb5_error_code LDB_unlock(krb5_context context, HDB *db) +static krb5_error_code hdb_samba4_unlock(krb5_context context, HDB *db) { return 0; } -static krb5_error_code LDB_rename(krb5_context context, HDB *db, const char *new_name) +static krb5_error_code hdb_samba4_rename(krb5_context context, HDB *db, const char *new_name) { return HDB_ERR_DB_INUSE; } -static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db, +static krb5_error_code hdb_samba4_fetch_client(krb5_context context, HDB *db, struct loadparm_context *lp_ctx, TALLOC_CTX *mem_ctx, krb5_const_principal principal, @@ -1008,13 +1008,13 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db, return EINVAL; } - ret = LDB_message2entry(context, db, lp_ctx, mem_ctx, + ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx, principal, HDB_SAMBA4_ENT_TYPE_CLIENT, realm_dn, msg, entry_ex); return ret; } -static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, +static krb5_error_code hdb_samba4_fetch_krbtgt(krb5_context context, HDB *db, struct loadparm_context *lp_ctx, TALLOC_CTX *mem_ctx, krb5_const_principal principal, @@ -1051,12 +1051,12 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, &msg, princ_attrs, "(&(objectClass=user)(samAccountName=krbtgt))"); if (lret == LDB_ERR_NO_SUCH_OBJECT) { - krb5_warnx(context, "LDB_fetch: could not find own KRBTGT in DB!"); - krb5_set_error_message(context, HDB_ERR_NOENTRY, "LDB_fetch: could not find own KRBTGT in DB!"); + krb5_warnx(context, "hdb_samba4_fetch: could not find own KRBTGT in DB!"); + krb5_set_error_message(context, HDB_ERR_NOENTRY, "hdb_samba4_fetch: could not find own KRBTGT in DB!"); return HDB_ERR_NOENTRY; } else if (lret != LDB_SUCCESS) { - krb5_warnx(context, "LDB_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db)); - krb5_set_error_message(context, HDB_ERR_NOENTRY, "LDB_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db)); + krb5_warnx(context, "hdb_samba4_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db)); + krb5_set_error_message(context, HDB_ERR_NOENTRY, "hdb_samba4_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db)); return HDB_ERR_NOENTRY; } @@ -1077,16 +1077,16 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, talloc_free(realm_fixed); if (!alloc_principal->name.name_string.val[1]) { ret = ENOMEM; - krb5_set_error_message(context, ret, "LDB_fetch: strdup() failed!"); + krb5_set_error_message(context, ret, "hdb_samba4_fetch: strdup() failed!"); return ret; } principal = alloc_principal; - ret = LDB_message2entry(context, db, lp_ctx, mem_ctx, + ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx, principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, realm_dn, msg, entry_ex); if (ret != 0) { - krb5_warnx(context, "LDB_fetch: self krbtgt message2entry failed"); + krb5_warnx(context, "hdb_samba4_fetch: self krbtgt message2entry failed"); } return ret; @@ -1109,21 +1109,21 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, /* Trusted domains are under CN=system */ - ret = LDB_lookup_trust(context, (struct ldb_context *)db->hdb_db, + ret = hdb_samba4_lookup_trust(context, (struct ldb_context *)db->hdb_db, mem_ctx, realm, realm_dn, &msg); if (ret != 0) { - krb5_warnx(context, "LDB_fetch: could not find principal in DB"); - krb5_set_error_message(context, ret, "LDB_fetch: could not find principal in DB"); + krb5_warnx(context, "hdb_samba4_fetch: could not find principal in DB"); + krb5_set_error_message(context, ret, "hdb_samba4_fetch: could not find principal in DB"); return ret; } - ret = LDB_trust_message2entry(context, db, lp_ctx, mem_ctx, + ret = hdb_samba4_trust_message2entry(context, db, lp_ctx, mem_ctx, principal, direction, realm_dn, msg, entry_ex); if (ret != 0) { - krb5_warnx(context, "LDB_fetch: trust_message2entry failed"); + krb5_warnx(context, "hdb_samba4_fetch: trust_message2entry failed"); } return ret; @@ -1134,7 +1134,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, } -static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, +static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db, struct loadparm_context *lp_ctx, TALLOC_CTX *mem_ctx, krb5_const_principal principal, @@ -1194,8 +1194,8 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, ret = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &short_princ); if (ret != 0) { - krb5_set_error_message(context, ret, "LDB_lookup_principal: could not parse principal"); - krb5_warnx(context, "LDB_lookup_principal: could not parse principal"); + krb5_set_error_message(context, ret, "hdb_samba4_lookup_principal: could not parse principal"); + krb5_warnx(context, "hdb_samba4_lookup_principal: could not parse principal"); return ret; } @@ -1215,46 +1215,46 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, } } - ret = LDB_message2entry(context, db, lp_ctx, mem_ctx, + ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx, principal, HDB_SAMBA4_ENT_TYPE_SERVER, realm_dn, msg, entry_ex); if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); + krb5_warnx(context, "hdb_samba4_fetch: message2entry failed"); } return ret; } -static krb5_error_code LDB_fetch(krb5_context context, HDB *db, +static krb5_error_code hdb_samba4_fetch(krb5_context context, HDB *db, krb5_const_principal principal, unsigned flags, hdb_entry_ex *entry_ex) { krb5_error_code ret = HDB_ERR_NOENTRY; - TALLOC_CTX *mem_ctx = talloc_named(db, 0, "LDB_fetch context"); + TALLOC_CTX *mem_ctx = talloc_named(db, 0, "hdb_samba4_fetch context"); struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context); if (!mem_ctx) { ret = ENOMEM; - krb5_set_error_message(context, ret, "LDB_fetch: talloc_named() failed!"); + krb5_set_error_message(context, ret, "hdb_samba4_fetch: talloc_named() failed!"); return ret; } if (flags & HDB_F_GET_CLIENT) { - ret = LDB_fetch_client(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex); + ret = hdb_samba4_fetch_client(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex); if (ret != HDB_ERR_NOENTRY) goto done; } if (flags & HDB_F_GET_SERVER) { /* krbtgt fits into this situation for trusted realms, and for resolving different versions of our own realm name */ - ret = LDB_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex); + ret = hdb_samba4_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex); if (ret != HDB_ERR_NOENTRY) goto done; /* We return 'no entry' if it does not start with krbtgt/, so move to the common case quickly */ - ret = LDB_fetch_server(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex); + ret = hdb_samba4_fetch_server(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex); if (ret != HDB_ERR_NOENTRY) goto done; } if (flags & HDB_F_GET_KRBTGT) { - ret = LDB_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex); + ret = hdb_samba4_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex); if (ret != HDB_ERR_NOENTRY) goto done; } @@ -1263,12 +1263,12 @@ done: return ret; } -static krb5_error_code LDB_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +static krb5_error_code hdb_samba4_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { return HDB_ERR_DB_INUSE; } -static krb5_error_code LDB_remove(krb5_context context, HDB *db, krb5_const_principal principal) +static krb5_error_code hdb_samba4_remove(krb5_context context, HDB *db, krb5_const_principal principal) { return HDB_ERR_DB_INUSE; } @@ -1282,7 +1282,7 @@ struct hdb_ldb_seq { struct ldb_dn *realm_dn; }; -static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +static krb5_error_code hdb_samba4_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { krb5_error_code ret; struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc; @@ -1294,16 +1294,16 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd return HDB_ERR_NOENTRY; } - mem_ctx = talloc_named(priv, 0, "LDB_seq context"); + mem_ctx = talloc_named(priv, 0, "hdb_samba4_seq context"); if (!mem_ctx) { ret = ENOMEM; - krb5_set_error_message(context, ret, "LDB_seq: talloc_named() failed!"); + krb5_set_error_message(context, ret, "hdb_samba4_seq: talloc_named() failed!"); return ret; } if (priv->index < priv->count) { - ret = LDB_message2entry(context, db, priv->lp_ctx, + ret = hdb_samba4_message2entry(context, db, priv->lp_ctx, mem_ctx, NULL, HDB_SAMBA4_ENT_TYPE_ANY, priv->realm_dn, priv->msgs[priv->index++], entry); @@ -1321,7 +1321,7 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd return ret; } -static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flags, +static krb5_error_code hdb_samba4_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db; @@ -1353,11 +1353,11 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag priv->realm_dn = ldb_get_default_basedn(ldb_ctx); priv->count = 0; - mem_ctx = talloc_named(priv, 0, "LDB_firstkey context"); + mem_ctx = talloc_named(priv, 0, "hdb_samba4_firstkey context"); if (!mem_ctx) { ret = ENOMEM; - krb5_set_error_message(context, ret, "LDB_firstkey: talloc_named() failed!"); + krb5_set_error_message(context, ret, "hdb_samba4_firstkey: talloc_named() failed!"); return ret; } @@ -1382,7 +1382,7 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag db->hdb_dbc = priv; - ret = LDB_seq(context, db, flags, entry); + ret = hdb_samba4_seq(context, db, flags, entry); if (ret != 0) { talloc_free(priv); @@ -1393,13 +1393,13 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag return ret; } -static krb5_error_code LDB_nextkey(krb5_context context, HDB *db, unsigned flags, +static krb5_error_code hdb_samba4_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { - return LDB_seq(context, db, flags, entry); + return hdb_samba4_seq(context, db, flags, entry); } -static krb5_error_code LDB_destroy(krb5_context context, HDB *db) +static krb5_error_code hdb_samba4_destroy(krb5_context context, HDB *db) { talloc_free(db); return 0; @@ -1451,22 +1451,22 @@ NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx, } (*db)->hdb_dbc = NULL; - (*db)->hdb_open = LDB_open; - (*db)->hdb_close = LDB_close; - (*db)->hdb_fetch = LDB_fetch; - (*db)->hdb_store = LDB_store; - (*db)->hdb_remove = LDB_remove; - (*db)->hdb_firstkey = LDB_firstkey; - (*db)->hdb_nextkey = LDB_nextkey; - (*db)->hdb_lock = LDB_lock; - (*db)->hdb_unlock = LDB_unlock; - (*db)->hdb_rename = LDB_rename; + (*db)->hdb_open = hdb_samba4_open; + (*db)->hdb_close = hdb_samba4_close; + (*db)->hdb_fetch = hdb_samba4_fetch; + (*db)->hdb_store = hdb_samba4_store; + (*db)->hdb_remove = hdb_samba4_remove; + (*db)->hdb_firstkey = hdb_samba4_firstkey; + (*db)->hdb_nextkey = hdb_samba4_nextkey; + (*db)->hdb_lock = hdb_samba4_lock; + (*db)->hdb_unlock = hdb_samba4_unlock; + (*db)->hdb_rename = hdb_samba4_rename; /* we don't implement these, as we are not a lockable database */ (*db)->hdb__get = NULL; (*db)->hdb__put = NULL; /* kadmin should not be used for deletes - use other tools instead */ (*db)->hdb__del = NULL; - (*db)->hdb_destroy = LDB_destroy; + (*db)->hdb_destroy = hdb_samba4_destroy; (*db)->hdb_auth_status = NULL; (*db)->hdb_check_constrained_delegation = NULL; -- cgit From 19bc4ce95ca9b2a985313f5eb887275aa6fe3599 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 16 Jul 2009 17:37:36 +1000 Subject: s4:kdc Rework KDC to pull in less attributes for krbtgt lookups Each attribute we request from LDB comes with a small cost, so don't lookup any more than we must for the (very) frequent krbtgt lookup case. Similarly, we don't need to build a PAC for a server (as a target), so don't ask for the PAC attributes here either. Andrew Bartlett --- source4/auth/auth.h | 2 ++ source4/auth/sam.c | 42 ++++++++++++++++++++++++++--------------- source4/kdc/hdb-samba4.c | 49 ++++++++++++++++++++++++++++++++---------------- 3 files changed, 62 insertions(+), 31 deletions(-) diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 6bad017862..8a0f12efd8 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -23,6 +23,8 @@ #include "librpc/gen_ndr/ndr_krb5pac.h" +extern const char *krbtgt_attrs[]; +extern const char *server_attrs[]; extern const char *user_attrs[]; union netr_Validation; diff --git a/source4/auth/sam.c b/source4/auth/sam.c index c396662c12..635d94242f 100644 --- a/source4/auth/sam.c +++ b/source4/auth/sam.c @@ -32,25 +32,37 @@ #include "param/param.h" #include "auth/auth_sam.h" -const char *user_attrs[] = { - /* required for the krb5 kdc */ - "objectClass", - "sAMAccountName", - "userPrincipalName", - "servicePrincipalName", - "msDS-KeyVersionNumber", - "supplementalCredentials", +#define KRBTGT_ATTRS \ + /* required for the krb5 kdc */ \ + "objectClass", \ + "sAMAccountName", \ + "userPrincipalName", \ + "servicePrincipalName", \ + "msDS-KeyVersionNumber", \ + "supplementalCredentials", \ + \ + /* passwords */ \ + "dBCSPwd", \ + "unicodePwd", \ + \ + "userAccountControl", \ + "objectSid", \ + \ + "pwdLastSet", \ + "accountExpires" + +const char *krbtgt_attrs[] = { + KRBTGT_ATTRS +}; - /* passwords */ - "dBCSPwd", - "unicodePwd", +const char *server_attrs[] = { + KRBTGT_ATTRS +}; - "userAccountControl", +const char *user_attrs[] = { + KRBTGT_ATTRS, - "pwdLastSet", - "accountExpires", "logonHours", - "objectSid", /* check 'allowed workstations' */ "userWorkstations", diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 25b0deb082..435282a0c1 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -1044,11 +1044,10 @@ static krb5_error_code hdb_samba4_fetch_krbtgt(krb5_context context, HDB *db, int lret; char *realm_fixed; - const char * const *princ_attrs = user_attrs; lret = gendb_search_single_extended_dn(db->hdb_db, mem_ctx, realm_dn, LDB_SCOPE_SUBTREE, - &msg, princ_attrs, + &msg, krbtgt_attrs, "(&(objectClass=user)(samAccountName=krbtgt))"); if (lret == LDB_ERR_NO_SUCH_OBJECT) { krb5_warnx(context, "hdb_samba4_fetch: could not find own KRBTGT in DB!"); @@ -1134,17 +1133,16 @@ static krb5_error_code hdb_samba4_fetch_krbtgt(krb5_context context, HDB *db, } -static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db, - struct loadparm_context *lp_ctx, - TALLOC_CTX *mem_ctx, - krb5_const_principal principal, - unsigned flags, - hdb_entry_ex *entry_ex) +static krb5_error_code hdb_samba4_lookup_server(krb5_context context, HDB *db, + struct loadparm_context *lp_ctx, + TALLOC_CTX *mem_ctx, + krb5_const_principal principal, + const char **attrs, + struct ldb_dn **realm_dn, + struct ldb_message **msg) { krb5_error_code ret; const char *realm; - struct ldb_message *msg = NULL; - struct ldb_dn *realm_dn; if (principal->name.name_string.len >= 2) { /* 'normal server' case */ int ldb_ret; @@ -1164,7 +1162,7 @@ static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db, * referral instead */ nt_status = crack_service_principal_name((struct ldb_context *)db->hdb_db, mem_ctx, principal_string, - &user_dn, &realm_dn); + &user_dn, realm_dn); free(principal_string); if (!NT_STATUS_IS_OK(nt_status)) { @@ -1174,7 +1172,7 @@ static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db, ldb_ret = gendb_search_single_extended_dn((struct ldb_context *)db->hdb_db, mem_ctx, user_dn, LDB_SCOPE_BASE, - &msg, user_attrs, + msg, attrs, "(objectClass=*)"); if (ldb_ret != LDB_SUCCESS) { return HDB_ERR_NOENTRY; @@ -1183,10 +1181,9 @@ static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db, } else { int lret; char *filter = NULL; - const char * const *princ_attrs = user_attrs; char *short_princ; /* server as client principal case, but we must not lookup userPrincipalNames */ - realm_dn = ldb_get_default_basedn(db->hdb_db); + *realm_dn = ldb_get_default_basedn(db->hdb_db); realm = krb5_principal_get_realm(context, principal); /* TODO: Check if it is our realm, otherwise give referall */ @@ -1200,8 +1197,8 @@ static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db, } lret = gendb_search_single_extended_dn(db->hdb_db, mem_ctx, - realm_dn, LDB_SCOPE_SUBTREE, - &msg, princ_attrs, "(&(objectClass=user)(samAccountName=%s))", + *realm_dn, LDB_SCOPE_SUBTREE, + msg, attrs, "(&(objectClass=user)(samAccountName=%s))", ldb_binary_encode_string(mem_ctx, short_princ)); free(short_princ); if (lret == LDB_ERR_NO_SUCH_OBJECT) { @@ -1215,6 +1212,26 @@ static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db, } } + return 0; +} + +static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db, + struct loadparm_context *lp_ctx, + TALLOC_CTX *mem_ctx, + krb5_const_principal principal, + unsigned flags, + hdb_entry_ex *entry_ex) +{ + krb5_error_code ret; + struct ldb_dn *realm_dn; + struct ldb_message *msg; + + ret = hdb_samba4_lookup_server(context, db, lp_ctx, mem_ctx, principal, + server_attrs, &realm_dn, &msg); + if (ret != 0) { + return ret; + } + ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx, principal, HDB_SAMBA4_ENT_TYPE_SERVER, realm_dn, msg, entry_ex); -- cgit From 6cb81f7b37d541efb54bcdca46b1e0f6bc8afef9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 Jul 2009 08:29:03 +1000 Subject: s4:heimdal: import lorikeet-heimdal-200907162216 (commit d09910d6803aad96b52ee626327ee55b14ea0de8) This includes in particular changes to the KDC to resolve bug 6272, originally by Matthieu Patou . We need to sort the AuthorizationData elements to put the PAC first, or else WinXP breaks when browsed from Win2k8. Andrew Bartlett --- source4/heimdal/kdc/krb5tgs.c | 39 +++++++++++++++++------------- source4/heimdal/lib/gssapi/gssapi/gssapi.h | 6 +++++ source4/heimdal/lib/hcrypto/des.h | 10 +++++--- source4/heimdal/lib/hcrypto/evp.h | 9 ++++++- source4/heimdal/lib/krb5/krb5.h | 6 +++++ source4/heimdal/lib/krb5/log.c | 13 +++++++++- 6 files changed, 60 insertions(+), 23 deletions(-) diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index 6b98506e81..635eb27e75 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -805,17 +805,34 @@ tgs_make_reply(krb5_context context, et.flags.hw_authent = tgt->flags.hw_authent; et.flags.anonymous = tgt->flags.anonymous; et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate; + + if(rspac->length) { + /* + * No not need to filter out the any PAC from the + * auth_data since it's signed by the KDC. + */ + ret = _kdc_tkt_add_if_relevant_ad(context, &et, + KRB5_AUTHDATA_WIN2K_PAC, rspac); + if (ret) + goto out; + } if (auth_data) { - /* XXX Check enc-authorization-data */ - et.authorization_data = calloc(1, sizeof(*et.authorization_data)); + unsigned int i = 0; + + /* XXX check authdata */ if (et.authorization_data == NULL) { ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } - ret = copy_AuthorizationData(auth_data, et.authorization_data); - if (ret) - goto out; + for(i = 0; i < auth_data->len ; i++) { + ret = add_AuthorizationData(et.authorization_data, &auth_data->val[i]); + if (ret) { + krb5_set_error_message(context, ret, "malloc: out of memory"); + goto out; + } + } /* Filter out type KRB5SignedPath */ ret = find_KRB5SignedPath(context, et.authorization_data, NULL); @@ -832,18 +849,6 @@ tgs_make_reply(krb5_context context, } } - if(rspac->length) { - /* - * No not need to filter out the any PAC from the - * auth_data since it's signed by the KDC. - */ - ret = _kdc_tkt_add_if_relevant_ad(context, &et, - KRB5_AUTHDATA_WIN2K_PAC, - rspac); - if (ret) - goto out; - } - ret = krb5_copy_keyblock_contents(context, sessionkey, &et.key); if (ret) goto out; diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h index 07c4b36325..91141808f5 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -54,7 +54,13 @@ #endif #ifndef GSSAPI_DEPRECATED +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 ))) #define GSSAPI_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define GSSAPI_DEPRECATED __declspec(deprecated) +#else +#define GSSAPI_DEPRECATED +#endif #endif /* diff --git a/source4/heimdal/lib/hcrypto/des.h b/source4/heimdal/lib/hcrypto/des.h index 14402d4b1c..99eb76c818 100644 --- a/source4/heimdal/lib/hcrypto/des.h +++ b/source4/heimdal/lib/hcrypto/des.h @@ -84,12 +84,14 @@ typedef struct DES_key_schedule * */ -#if !defined(__GNUC__) && !defined(__attribute__) -#define __attribute__(x) -#endif - #ifndef HC_DEPRECATED +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 ))) #define HC_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) && (_MSC_VER>1200) +#define HC_DEPRECATED __declspec(deprecated) +#else +#define HC_DEPRECATED +#endif #endif #ifdef __cplusplus diff --git a/source4/heimdal/lib/hcrypto/evp.h b/source4/heimdal/lib/hcrypto/evp.h index a7c8fac900..0086a06960 100644 --- a/source4/heimdal/lib/hcrypto/evp.h +++ b/source4/heimdal/lib/hcrypto/evp.h @@ -190,10 +190,17 @@ struct hc_evp_md { #endif #ifndef HC_DEPRECATED +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 ))) #define HC_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) && (_MSC_VER>1200) +#define HC_DEPRECATED __declspec(deprecated) +#else +#define HC_DEPRECATED #endif +#endif + #ifndef HC_DEPRECATED_CRYPTO -#define HC_DEPRECATED_CRYPTO __attribute__((deprecated)) +#define HC_DEPRECATED_CRYPTO HC_DEPRECATED #endif diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 13dafacf21..1f2e769728 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -52,7 +52,13 @@ #endif #ifndef KRB5_DEPRECATED +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 ))) #define KRB5_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) && (_MSC_VER>1200) +#define KRB5_DEPRECATED __declspec(deprecated) +#else +#define KRB5_DEPRECATED +#endif #endif /* simple constants */ diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c index 31d267320f..ee5c1159b1 100644 --- a/source4/heimdal/lib/krb5/log.c +++ b/source4/heimdal/lib/krb5/log.c @@ -32,6 +32,7 @@ */ #include "krb5_locl.h" +#include struct facility { int min; @@ -218,11 +219,21 @@ log_file(const char *timestr, void *data) { struct file_data *f = data; + char *msgclean; + size_t len = strlen(msg) + 1; if(f->keep_open == 0) f->fd = fopen(f->filename, f->mode); if(f->fd == NULL) return; - fprintf(f->fd, "%s %s\n", timestr, msg); + /* make sure the log doesn't contain special chars */ + len *= 4; + msgclean = malloc(len); + if (msgclean == NULL) + goto out; + strvisx(rk_UNCONST(msg), msgclean, len, VIS_OCTAL); + fprintf(f->fd, "%s %s\n", timestr, msgclean); + free(msgclean); + out: if(f->keep_open == 0) { fclose(f->fd); f->fd = NULL; -- cgit From f6bed79ec6f287ac5da79151b97b6cf4776aab7a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 Jul 2009 08:39:51 +1000 Subject: Revert "s4:heimdal_build: predefine GSSAPI_DEPRECATED depending on the compiler version" This is now handled correctly in the newly imported Heimdal This reverts commit 4a754d029b0eb229b23980aa4a80dae2b485a302. --- source4/heimdal_build/krb5-types.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source4/heimdal_build/krb5-types.h b/source4/heimdal_build/krb5-types.h index 94973d7fbe..cdc5a3cba9 100644 --- a/source4/heimdal_build/krb5-types.h +++ b/source4/heimdal_build/krb5-types.h @@ -10,12 +10,4 @@ typedef socklen_t krb5_socklen_t; typedef ssize_t krb5_ssize_t; -#ifndef GSSAPI_DEPRECATED -#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) -#define GSSAPI_DEPRECATED __attribute__ ((deprecated)) -#else -#define GSSAPI_DEPRECATED -#endif -#endif - #endif /* __krb5_types_h__ */ -- cgit From 9f0bdd4e17ef5fe0b28a8ec4676d19eb4ffe6786 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 2009 18:12:17 -0700 Subject: Remove an unused talloc context. Jeremy. --- source3/auth/auth.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/source3/auth/auth.c b/source3/auth/auth.c index fd4c503752..ce8722a1b4 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -82,7 +82,6 @@ static void get_ntlm_challenge(struct auth_context *auth_context, DATA_BLOB challenge = data_blob_null; const char *challenge_set_by = NULL; auth_methods *auth_method; - TALLOC_CTX *mem_ctx; if (auth_context->challenge.length) { DEBUG(5, ("get_ntlm_challenge (auth subsystem): returning previous challenge by module %s (normal)\n", @@ -106,12 +105,8 @@ static void get_ntlm_challenge(struct auth_context *auth_context, continue; } - mem_ctx = talloc_init("auth_get_challenge for module %s", auth_method->name); - if (!mem_ctx) { - smb_panic("talloc_init() failed!"); - } - - challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx); + challenge = auth_method->get_chal(auth_context, &auth_method->private_data, + auth_context->mem_ctx); if (!challenge.length) { DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n", auth_method->name)); @@ -121,7 +116,6 @@ static void get_ntlm_challenge(struct auth_context *auth_context, challenge_set_by = auth_method->name; auth_context->challenge_set_method = auth_method; } - talloc_destroy(mem_ctx); } if (!challenge_set_by) { -- cgit From d5c20c072b464b675fbd5f37a94ae8a6ad403d49 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 2009 18:13:46 -0700 Subject: Replace short-lived NULL talloc contexts with talloc_tos(). Jeremy. --- source3/lib/charcnv.c | 8 ++++---- source3/lib/dbwrap_tdb.c | 2 +- source3/lib/util_str.c | 34 +++++++++++++++++----------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index a1663c1f38..272f107138 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -753,7 +753,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) size_t size; smb_ucs2_t *buffer; - if (!push_ucs2_talloc(NULL, &buffer, src, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) { return (size_t)-1; } @@ -837,7 +837,7 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) size_t size; smb_ucs2_t *buffer = NULL; - if (!convert_string_talloc(NULL, CH_UNIX, CH_UTF16LE, src, srclen, + if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen, (void **)(void *)&buffer, &size, True)) { @@ -951,7 +951,7 @@ size_t push_ascii_nstring(void *dest, const char *src) smb_ucs2_t *buffer; conv_silent = True; - if (!push_ucs2_talloc(NULL, &buffer, src, &buffer_len)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &buffer_len)) { smb_panic("failed to create UCS2 buffer"); } @@ -1268,7 +1268,7 @@ static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags) } if (flags & STR_UPPER) { - tmpbuf = strupper_talloc(NULL, src); + tmpbuf = strupper_talloc(talloc_tos(), src); if (!tmpbuf) { return (size_t)-1; } diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index c71e073b41..297a351764 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -94,7 +94,7 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db, /* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */ if(DEBUGLEVEL >= 10) { - char *keystr = hex_encode_talloc(NULL, (unsigned char*)key.dptr, key.dsize); + char *keystr = hex_encode_talloc(talloc_tos(), (unsigned char*)key.dptr, key.dsize); DEBUG(10, (DEBUGLEVEL > 10 ? "Locking key %s\n" : "Locking key %.20s\n", keystr)); diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 0aff9439e9..c197fd7515 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -96,14 +96,14 @@ int StrCaseCmp(const char *s, const char *t) return +1; } - if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) { return strcmp(ps, pt); /* Not quite the right answer, but finding the right one under this failure case is expensive, and it's pretty close */ } - if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) { TALLOC_FREE(buffer_s); return strcmp(ps, pt); /* Not quite the right answer, but finding the right one @@ -157,14 +157,14 @@ int StrnCaseCmp(const char *s, const char *t, size_t len) return 0; } - if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) { return strncmp(ps, pt, len-n); /* Not quite the right answer, but finding the right one under this failure case is expensive, and it's pretty close */ } - if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) { TALLOC_FREE(buffer_s); return strncmp(ps, pt, len-n); /* Not quite the right answer, but finding the right one @@ -366,7 +366,7 @@ size_t str_charnum(const char *s) { size_t ret, converted_size; smb_ucs2_t *tmpbuf2 = NULL; - if (!push_ucs2_talloc(NULL, &tmpbuf2, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) { return 0; } ret = strlen_w(tmpbuf2); @@ -384,7 +384,7 @@ size_t str_ascii_charnum(const char *s) { size_t ret, converted_size; char *tmpbuf2 = NULL; - if (!push_ascii_talloc(NULL, &tmpbuf2, s, &converted_size)) { + if (!push_ascii_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) { return 0; } ret = strlen(tmpbuf2); @@ -455,7 +455,7 @@ bool strhasupper(const char *s) bool ret; size_t converted_size; - if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) { return false; } @@ -480,7 +480,7 @@ bool strhaslower(const char *s) bool ret; size_t converted_size; - if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) { return false; } @@ -1177,7 +1177,7 @@ char *strchr_m(const char *src, char c) s = src; #endif - if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) { /* Wrong answer, but what can we do... */ return strchr(src, c); } @@ -1187,7 +1187,7 @@ char *strchr_m(const char *src, char c) return NULL; } *p = 0; - if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) { + if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) { SAFE_FREE(ws); /* Wrong answer, but what can we do... */ return strchr(src, c); @@ -1248,7 +1248,7 @@ char *strrchr_m(const char *s, char c) char *ret; size_t converted_size; - if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) { /* Wrong answer, but what can we do. */ return strrchr(s, c); } @@ -1258,7 +1258,7 @@ char *strrchr_m(const char *s, char c) return NULL; } *p = 0; - if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) { + if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) { TALLOC_FREE(ws); /* Wrong answer, but what can we do. */ return strrchr(s, c); @@ -1283,7 +1283,7 @@ char *strnrchr_m(const char *s, char c, unsigned int n) char *ret; size_t converted_size; - if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) { /* Too hard to try and get right. */ return NULL; } @@ -1293,7 +1293,7 @@ char *strnrchr_m(const char *s, char c, unsigned int n) return NULL; } *p = 0; - if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) { + if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) { TALLOC_FREE(ws); /* Too hard to try and get right. */ return NULL; @@ -1352,12 +1352,12 @@ char *strstr_m(const char *src, const char *findstr) s = src; #endif - if (!push_ucs2_talloc(NULL, &src_w, src, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) { DEBUG(0,("strstr_m: src malloc fail\n")); return NULL; } - if (!push_ucs2_talloc(NULL, &find_w, findstr, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) { TALLOC_FREE(src_w); DEBUG(0,("strstr_m: find malloc fail\n")); return NULL; @@ -1372,7 +1372,7 @@ char *strstr_m(const char *src, const char *findstr) } *p = 0; - if (!pull_ucs2_talloc(NULL, &s2, src_w, &converted_size)) { + if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) { TALLOC_FREE(src_w); TALLOC_FREE(find_w); DEBUG(0,("strstr_m: dest malloc fail\n")); -- cgit From d4a87ee966adb9205169507fca5c07faefc4513e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 2009 18:14:56 -0700 Subject: Replace more long-lived contexts with talloc_autofree_context(). Jeremy. --- source3/lib/ctdbd_conn.c | 2 +- source3/libsmb/spnego.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index dde377581b..449e049ffa 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -358,7 +358,7 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid, goto next_pkt; } - if (!(msg_state = TALLOC_P(NULL, struct deferred_msg_state))) { + if (!(msg_state = TALLOC_P(talloc_autofree_context(), struct deferred_msg_state))) { DEBUG(0, ("talloc failed\n")); TALLOC_FREE(hdr); goto next_pkt; diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index ee2c3c3d5a..3fa9559cfb 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -41,7 +41,7 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - token->mechTypes = TALLOC_P(NULL, const char *); + token->mechTypes = TALLOC_P(talloc_autofree_context(), const char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { const char *p_oid = NULL; -- cgit From 5f295eb6f5fe60394b764a2e0bc76b77f6160664 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 2009 18:28:58 -0700 Subject: More conversions of NULL -> talloc_autofree_context() so we at least know when we're using a long-lived context. Jeremy. --- source3/libsmb/clikrb5.c | 4 ++-- source3/libsmb/clispnego.c | 18 +++++++++--------- source3/libsmb/spnego.c | 21 +++++++++++++-------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 8a567dc751..152c23bd15 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -346,7 +346,7 @@ bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx, } asn1_start_tag(data, ASN1_CONTEXT(2)); - asn1_read_OctetString(data, NULL, &edata_contents); + asn1_read_OctetString(data, talloc_autofree_context(), &edata_contents); asn1_end_tag(data); asn1_end_tag(data); asn1_end_tag(data); @@ -389,7 +389,7 @@ bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ asn1_end_tag(data); asn1_start_tag(data, ASN1_CONTEXT(1)); - asn1_read_OctetString(data, NULL, &pac_contents); + asn1_read_OctetString(data, talloc_autofree_context(), &pac_contents); asn1_end_tag(data); asn1_end_tag(data); asn1_end_tag(data); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index fb95d71925..e586d976cf 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -151,7 +151,7 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(data,ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) { const char *oid_str = NULL; - asn1_read_OID(data,NULL,&oid_str); + asn1_read_OID(data,talloc_autofree_context(),&oid_str); OIDs[i] = CONST_DISCARD(char *, oid_str); } OIDs[i] = NULL; @@ -163,7 +163,7 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(data, ASN1_CONTEXT(3)); asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_start_tag(data, ASN1_CONTEXT(0)); - asn1_read_GeneralString(data,NULL,principal); + asn1_read_GeneralString(data,talloc_autofree_context(),principal); asn1_end_tag(data); asn1_end_tag(data); asn1_end_tag(data); @@ -256,7 +256,7 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_start_tag(data, ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) { const char *oid_str = NULL; - asn1_read_OID(data,NULL,&oid_str); + asn1_read_OID(data,talloc_autofree_context(),&oid_str); OIDs[i] = CONST_DISCARD(char *, oid_str); } OIDs[i] = NULL; @@ -276,7 +276,7 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se } asn1_start_tag(data, ASN1_CONTEXT(2)); - asn1_read_OctetString(data,NULL,secblob); + asn1_read_OctetString(data,talloc_autofree_context(),secblob); asn1_end_tag(data); asn1_end_tag(data); @@ -436,13 +436,13 @@ bool spnego_parse_challenge(const DATA_BLOB blob, asn1_end_tag(data); asn1_start_tag(data,ASN1_CONTEXT(2)); - asn1_read_OctetString(data, NULL, chal1); + asn1_read_OctetString(data, talloc_autofree_context(), chal1); asn1_end_tag(data); /* the second challenge is optional (XP doesn't send it) */ if (asn1_tag_remaining(data)) { asn1_start_tag(data,ASN1_CONTEXT(3)); - asn1_read_OctetString(data, NULL, chal2); + asn1_read_OctetString(data, talloc_autofree_context(), chal2); asn1_end_tag(data); } @@ -505,7 +505,7 @@ bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) asn1_start_tag(data, ASN1_CONTEXT(1)); asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_start_tag(data, ASN1_CONTEXT(2)); - asn1_read_OctetString(data, NULL, auth); + asn1_read_OctetString(data, talloc_autofree_context(), auth); asn1_end_tag(data); asn1_end_tag(data); asn1_end_tag(data); @@ -609,7 +609,7 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, if (asn1_tag_remaining(data)) { asn1_start_tag(data,ASN1_CONTEXT(2)); - asn1_read_OctetString(data, NULL, auth); + asn1_read_OctetString(data, talloc_autofree_context(), auth); asn1_end_tag(data); } } else if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { @@ -623,7 +623,7 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, if (asn1_tag_remaining(data)) { DATA_BLOB mechList = data_blob_null; asn1_start_tag(data, ASN1_CONTEXT(3)); - asn1_read_OctetString(data, NULL, &mechList); + asn1_read_OctetString(data, talloc_autofree_context(), &mechList); asn1_end_tag(data); data_blob_free(&mechList); DEBUG(5,("spnego_parse_auth_response received mechListMIC, " diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 3fa9559cfb..528c7f4009 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -46,12 +46,13 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) 0 < asn1_tag_remaining(asn1); i++) { const char *p_oid = NULL; token->mechTypes = - TALLOC_REALLOC_ARRAY(NULL, token->mechTypes, const char *, i + 2); + TALLOC_REALLOC_ARRAY(talloc_autofree_context(), + token->mechTypes, const char *, i + 2); if (!token->mechTypes) { asn1->has_error = True; return False; } - asn1_read_OID(asn1, NULL, &p_oid); + asn1_read_OID(asn1, talloc_autofree_context(), &p_oid); token->mechTypes[i] = p_oid; } token->mechTypes[i] = NULL; @@ -69,14 +70,15 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) /* Read mechToken */ case ASN1_CONTEXT(2): asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, NULL, &token->mechToken); + asn1_read_OctetString(asn1, + talloc_autofree_context(), &token->mechToken); asn1_end_tag(asn1); break; /* Read mecListMIC */ case ASN1_CONTEXT(3): asn1_start_tag(asn1, ASN1_CONTEXT(3)); if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) { - asn1_read_OctetString(asn1, NULL, + asn1_read_OctetString(asn1, talloc_autofree_context(), &token->mechListMIC); } else { /* RFC 2478 says we have an Octet String here, @@ -84,7 +86,8 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) char *mechListMIC; asn1_push_tag(asn1, ASN1_SEQUENCE(0)); asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_read_GeneralString(asn1, NULL, &mechListMIC); + asn1_read_GeneralString(asn1, + talloc_autofree_context(), &mechListMIC); asn1_pop_tag(asn1); asn1_pop_tag(asn1); @@ -188,19 +191,21 @@ static bool read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) case ASN1_CONTEXT(1): { const char *mech = NULL; asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_OID(asn1, NULL, &mech); + asn1_read_OID(asn1, talloc_autofree_context(), &mech); asn1_end_tag(asn1); token->supportedMech = CONST_DISCARD(char *, mech); } break; case ASN1_CONTEXT(2): asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, NULL, &token->responseToken); + asn1_read_OctetString(asn1, + talloc_autofree_context(), &token->responseToken); asn1_end_tag(asn1); break; case ASN1_CONTEXT(3): asn1_start_tag(asn1, ASN1_CONTEXT(3)); - asn1_read_OctetString(asn1, NULL, &token->mechListMIC); + asn1_read_OctetString(asn1, + talloc_autofree_context(), &token->mechListMIC); asn1_end_tag(asn1); break; default: -- cgit From 20f40d1c5065d909f4274b86de20fa941fa20405 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Sat, 18 Jul 2009 08:01:56 +0800 Subject: s3: Fix crsh in net usershare list Signed-off-by: Bo Yang --- source3/utils/net_usershare.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/utils/net_usershare.c b/source3/utils/net_usershare.c index d82d30bc2d..6eacb1386c 100644 --- a/source3/utils/net_usershare.c +++ b/source3/utils/net_usershare.c @@ -974,6 +974,7 @@ static int net_usershare_list(struct net_context *c, int argc, pi.ctx = ctx; pi.op = US_LIST_OP; + pi.c = c; ret = process_share_list(info_fn, &pi); talloc_destroy(ctx); -- cgit From e7daa0d7049933e5a743f7e6db886f624490c53d Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Sat, 18 Jul 2009 08:03:57 +0800 Subject: s3: don't do this, upper callbacks will check it Signed-off-by: Bo Yang --- source3/winbindd/winbindd_dual.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 92f0d60817..ab07c9767d 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -179,10 +179,6 @@ int wb_child_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, if (tevent_req_is_unix_error(req, err)) { return -1; } - if (state->response->result != WINBINDD_OK) { - *err = EIO; /* EIO doesn't fit, but what would be better? */ - return -1; - } *presponse = talloc_move(mem_ctx, &state->response); return 0; } -- cgit From b180fe34a71a595d0dea8e72877149361b531e02 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Sat, 18 Jul 2009 10:46:11 +0800 Subject: s3: compile warning and upn handling Signed-off-by: Bo Yang --- nsswitch/pam_winbind.c | 37 ++++++++++++++++++++++++------------- source3/winbindd/winbindd_sid.c | 5 +++++ source3/winbindd/winbindd_util.c | 3 ++- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c index e90f1b75ad..f692316fc6 100644 --- a/nsswitch/pam_winbind.c +++ b/nsswitch/pam_winbind.c @@ -11,6 +11,8 @@ */ #include "pam_winbind.h" +#define CONST_DISCARD(type,ptr) ((type)(void *)ptr) + static int wbc_error_to_pam_error(wbcErr status) { @@ -410,49 +412,51 @@ static int _pam_parse(const pam_handle_t *pamh, config_file = PAM_WINBIND_CONFIG_FILE; } - d = iniparser_load(config_file); + d = iniparser_load(CONST_DISCARD(char *, config_file)); if (d == NULL) { goto config_from_pam; } - if (iniparser_getboolean(d, "global:debug", false)) { + if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:debug"), false)) { ctrl |= WINBIND_DEBUG_ARG; } - if (iniparser_getboolean(d, "global:debug_state", false)) { + if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:debug_state"), false)) { ctrl |= WINBIND_DEBUG_STATE; } - if (iniparser_getboolean(d, "global:cached_login", false)) { + if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:cached_login"), false)) { ctrl |= WINBIND_CACHED_LOGIN; } - if (iniparser_getboolean(d, "global:krb5_auth", false)) { + if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:krb5_auth"), false)) { ctrl |= WINBIND_KRB5_AUTH; } - if (iniparser_getboolean(d, "global:silent", false)) { + if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:silent"), false)) { ctrl |= WINBIND_SILENT; } - if (iniparser_getstr(d, "global:krb5_ccache_type") != NULL) { + if (iniparser_getstr(d, CONST_DISCARD(char *, "global:krb5_ccache_type")) != NULL) { ctrl |= WINBIND_KRB5_CCACHE_TYPE; } - if ((iniparser_getstr(d, "global:require-membership-of") != NULL) || - (iniparser_getstr(d, "global:require_membership_of") != NULL)) { + if ((iniparser_getstr(d, CONST_DISCARD(char *, "global:require-membership-of")) + != NULL) || + (iniparser_getstr(d, CONST_DISCARD(char *, "global:require_membership_of")) + != NULL)) { ctrl |= WINBIND_REQUIRED_MEMBERSHIP; } - if (iniparser_getboolean(d, "global:try_first_pass", false)) { + if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:try_first_pass"), false)) { ctrl |= WINBIND_TRY_FIRST_PASS_ARG; } - if (iniparser_getint(d, "global:warn_pwd_expire", 0)) { + if (iniparser_getint(d, CONST_DISCARD(char *, "global:warn_pwd_expire"), 0)) { ctrl |= WINBIND_WARN_PWD_EXPIRE; } - if (iniparser_getboolean(d, "global:mkhomedir", false)) { + if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:mkhomedir"), false)) { ctrl |= WINBIND_MKHOMEDIR; } @@ -2284,6 +2288,7 @@ static char* winbind_upn_to_username(struct pwb_context *ctx, enum wbcSidType type; char *domain; char *name; + char *p; /* This cannot work when the winbind separator = @ */ @@ -2292,9 +2297,15 @@ static char* winbind_upn_to_username(struct pwb_context *ctx, return NULL; } + name = talloc_strdup(ctx, upn); + if ((p = strchr(name, '@')) != NULL) { + *p = 0; + domain = talloc_strdup(ctx, p + 1); + } + /* Convert the UPN to a SID */ - wbc_status = wbcLookupName("", upn, &sid, &type); + wbc_status = wbcLookupName(domain, name, &sid, &type); if (!WBC_ERROR_IS_OK(wbc_status)) { return NULL; } diff --git a/source3/winbindd/winbindd_sid.c b/source3/winbindd/winbindd_sid.c index c091cd7f53..f8cf7db920 100644 --- a/source3/winbindd/winbindd_sid.c +++ b/source3/winbindd/winbindd_sid.c @@ -93,6 +93,11 @@ void winbindd_lookupname(struct winbindd_cli_state *state) *p = 0; name_domain = state->request->data.name.name; name_user = p+1; + } else if ((p = strchr(state->request->data.name.name, '@')) != NULL) { + /* upn */ + name_domain = p + 1; + *p = 0; + name_user = state->request->data.name.name; } else { name_domain = state->request->data.name.dom_name; name_user = state->request->data.name.name; diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 283eee09af..44ae814ae9 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -996,7 +996,8 @@ bool parse_domain_user(const char *domuser, fstring domain, fstring user) if ( assume_domain(lp_workgroup())) { fstrcpy(domain, lp_workgroup()); } else if ((p = strchr(domuser, '@')) != NULL) { - fstrcpy(domain, ""); + fstrcpy(domain, p + 1); + user[PTR_DIFF(p, domuser)] = 0; } else { return False; } -- cgit From 9ac5f5c8ce6b82d26ed6efc4632e08182d2fda39 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 13:09:26 +0200 Subject: lsa: fill in lsa_StorePrivateData and lsa_RetrievePrivateData and rerun make samba3-idl. Guenther --- librpc/gen_ndr/cli_lsa.c | 17 ++++- librpc/gen_ndr/cli_lsa.h | 10 ++- librpc/gen_ndr/lsa.h | 13 ++++ librpc/gen_ndr/ndr_lsa.c | 163 +++++++++++++++++++++++++++++++++++++++++++++++ librpc/gen_ndr/srv_lsa.c | 4 ++ librpc/idl/lsa.idl | 14 +++- 6 files changed, 214 insertions(+), 7 deletions(-) diff --git a/librpc/gen_ndr/cli_lsa.c b/librpc/gen_ndr/cli_lsa.c index 93362537b4..04cf38aaf3 100644 --- a/librpc/gen_ndr/cli_lsa.c +++ b/librpc/gen_ndr/cli_lsa.c @@ -1796,12 +1796,18 @@ NTSTATUS rpccli_lsa_DeleteTrustedDomain(struct rpc_pipe_client *cli, } NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx) + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + struct lsa_String *name /* [in] [ref] */, + struct lsa_DATA_BUF *val /* [in] [unique] */) { struct lsa_StorePrivateData r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.name = name; + r.in.val = val; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(lsa_StorePrivateData, &r); @@ -1832,12 +1838,18 @@ NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli, } NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx) + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + struct lsa_String *name /* [in] [ref] */, + struct lsa_DATA_BUF **val /* [in,out] [ref] */) { struct lsa_RetrievePrivateData r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.name = name; + r.in.val = val; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(lsa_RetrievePrivateData, &r); @@ -1862,6 +1874,7 @@ NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli, } /* Return variables */ + *val = *r.out.val; /* Return result */ return r.out.result; diff --git a/librpc/gen_ndr/cli_lsa.h b/librpc/gen_ndr/cli_lsa.h index 8dbd7330b4..10c408528f 100644 --- a/librpc/gen_ndr/cli_lsa.h +++ b/librpc/gen_ndr/cli_lsa.h @@ -214,9 +214,15 @@ NTSTATUS rpccli_lsa_DeleteTrustedDomain(struct rpc_pipe_client *cli, struct policy_handle *handle /* [in] [ref] */, struct dom_sid2 *dom_sid /* [in] [ref] */); NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx); + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + struct lsa_String *name /* [in] [ref] */, + struct lsa_DATA_BUF *val /* [in] [unique] */); NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx); + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + struct lsa_String *name /* [in] [ref] */, + struct lsa_DATA_BUF **val /* [in,out] [ref] */); NTSTATUS rpccli_lsa_OpenPolicy2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *system_name /* [in] [unique,charset(UTF16)] */, diff --git a/librpc/gen_ndr/lsa.h b/librpc/gen_ndr/lsa.h index 06fa44577e..9ee5fab4c8 100644 --- a/librpc/gen_ndr/lsa.h +++ b/librpc/gen_ndr/lsa.h @@ -1332,6 +1332,12 @@ struct lsa_DeleteTrustedDomain { struct lsa_StorePrivateData { + struct { + struct policy_handle *handle;/* [ref] */ + struct lsa_String *name;/* [ref] */ + struct lsa_DATA_BUF *val;/* [unique] */ + } in; + struct { NTSTATUS result; } out; @@ -1341,6 +1347,13 @@ struct lsa_StorePrivateData { struct lsa_RetrievePrivateData { struct { + struct policy_handle *handle;/* [ref] */ + struct lsa_String *name;/* [ref] */ + struct lsa_DATA_BUF **val;/* [ref] */ + } in; + + struct { + struct lsa_DATA_BUF **val;/* [ref] */ NTSTATUS result; } out; diff --git a/librpc/gen_ndr/ndr_lsa.c b/librpc/gen_ndr/ndr_lsa.c index 2b12bbff90..b8ba679378 100644 --- a/librpc/gen_ndr/ndr_lsa.c +++ b/librpc/gen_ndr/ndr_lsa.c @@ -9225,6 +9225,18 @@ _PUBLIC_ void ndr_print_lsa_DeleteTrustedDomain(struct ndr_print *ndr, const cha static enum ndr_err_code ndr_push_lsa_StorePrivateData(struct ndr_push *ndr, int flags, const struct lsa_StorePrivateData *r) { if (flags & NDR_IN) { + if (r->in.handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle)); + if (r->in.name == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.val)); + if (r->in.val) { + NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.val)); + } } if (flags & NDR_OUT) { NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); @@ -9234,7 +9246,37 @@ static enum ndr_err_code ndr_push_lsa_StorePrivateData(struct ndr_push *ndr, int static enum ndr_err_code ndr_pull_lsa_StorePrivateData(struct ndr_pull *ndr, int flags, struct lsa_StorePrivateData *r) { + uint32_t _ptr_val; + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_name_0; + TALLOC_CTX *_mem_save_val_0; if (flags & NDR_IN) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.handle); + } + _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.name); + } + _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.name, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val)); + if (_ptr_val) { + NDR_PULL_ALLOC(ndr, r->in.val); + } else { + r->in.val = NULL; + } + if (r->in.val) { + _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.val, 0); + NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.val)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, 0); + } } if (flags & NDR_OUT) { NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); @@ -9252,6 +9294,20 @@ _PUBLIC_ void ndr_print_lsa_StorePrivateData(struct ndr_print *ndr, const char * if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "lsa_StorePrivateData"); ndr->depth++; + ndr_print_ptr(ndr, "handle", r->in.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->in.handle); + ndr->depth--; + ndr_print_ptr(ndr, "name", r->in.name); + ndr->depth++; + ndr_print_lsa_String(ndr, "name", r->in.name); + ndr->depth--; + ndr_print_ptr(ndr, "val", r->in.val); + ndr->depth++; + if (r->in.val) { + ndr_print_lsa_DATA_BUF(ndr, "val", r->in.val); + } + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { @@ -9266,8 +9322,30 @@ _PUBLIC_ void ndr_print_lsa_StorePrivateData(struct ndr_print *ndr, const char * static enum ndr_err_code ndr_push_lsa_RetrievePrivateData(struct ndr_push *ndr, int flags, const struct lsa_RetrievePrivateData *r) { if (flags & NDR_IN) { + if (r->in.handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle)); + if (r->in.name == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name)); + if (r->in.val == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->in.val)); + if (*r->in.val) { + NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.val)); + } } if (flags & NDR_OUT) { + if (r->out.val == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.val)); + if (*r->out.val) { + NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.val)); + } NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -9275,9 +9353,68 @@ static enum ndr_err_code ndr_push_lsa_RetrievePrivateData(struct ndr_push *ndr, static enum ndr_err_code ndr_pull_lsa_RetrievePrivateData(struct ndr_pull *ndr, int flags, struct lsa_RetrievePrivateData *r) { + uint32_t _ptr_val; + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_name_0; + TALLOC_CTX *_mem_save_val_0; + TALLOC_CTX *_mem_save_val_1; if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.handle); + } + _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.name); + } + _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.name, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, LIBNDR_FLAG_REF_ALLOC); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.val); + } + _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.val, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val)); + if (_ptr_val) { + NDR_PULL_ALLOC(ndr, *r->in.val); + } else { + *r->in.val = NULL; + } + if (*r->in.val) { + _mem_save_val_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->in.val, 0); + NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.val)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_1, 0); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, LIBNDR_FLAG_REF_ALLOC); + NDR_PULL_ALLOC(ndr, r->out.val); + *r->out.val = *r->in.val; } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.val); + } + _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.val, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val)); + if (_ptr_val) { + NDR_PULL_ALLOC(ndr, *r->out.val); + } else { + *r->out.val = NULL; + } + if (*r->out.val) { + _mem_save_val_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.val, 0); + NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.val)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_1, 0); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -9293,11 +9430,37 @@ _PUBLIC_ void ndr_print_lsa_RetrievePrivateData(struct ndr_print *ndr, const cha if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "lsa_RetrievePrivateData"); ndr->depth++; + ndr_print_ptr(ndr, "handle", r->in.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->in.handle); + ndr->depth--; + ndr_print_ptr(ndr, "name", r->in.name); + ndr->depth++; + ndr_print_lsa_String(ndr, "name", r->in.name); + ndr->depth--; + ndr_print_ptr(ndr, "val", r->in.val); + ndr->depth++; + ndr_print_ptr(ndr, "val", *r->in.val); + ndr->depth++; + if (*r->in.val) { + ndr_print_lsa_DATA_BUF(ndr, "val", *r->in.val); + } + ndr->depth--; + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "lsa_RetrievePrivateData"); ndr->depth++; + ndr_print_ptr(ndr, "val", r->out.val); + ndr->depth++; + ndr_print_ptr(ndr, "val", *r->out.val); + ndr->depth++; + if (*r->out.val) { + ndr_print_lsa_DATA_BUF(ndr, "val", *r->out.val); + } + ndr->depth--; + ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; } diff --git a/librpc/gen_ndr/srv_lsa.c b/librpc/gen_ndr/srv_lsa.c index c86d0857f8..f1b4a06d0d 100644 --- a/librpc/gen_ndr/srv_lsa.c +++ b/librpc/gen_ndr/srv_lsa.c @@ -3366,6 +3366,8 @@ static bool api_lsa_RetrievePrivateData(pipes_struct *p) NDR_PRINT_IN_DEBUG(lsa_RetrievePrivateData, r); } + ZERO_STRUCT(r->out); + r->out.val = r->in.val; r->out.result = _lsa_RetrievePrivateData(p, r); if (p->rng_fault_state) { @@ -6810,6 +6812,8 @@ NTSTATUS rpc_lsarpc_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, c case NDR_LSA_RETRIEVEPRIVATEDATA: { struct lsa_RetrievePrivateData *r = (struct lsa_RetrievePrivateData *)_r; + ZERO_STRUCT(r->out); + r->out.val = r->in.val; r->out.result = _lsa_RetrievePrivateData(cli->pipes_struct, r); return NT_STATUS_OK; } diff --git a/librpc/idl/lsa.idl b/librpc/idl/lsa.idl index 3d7077ccac..7f8ed4afe3 100644 --- a/librpc/idl/lsa.idl +++ b/librpc/idl/lsa.idl @@ -935,10 +935,18 @@ import "misc.idl", "security.idl"; ); /* Function: 0x2a */ - [todo] NTSTATUS lsa_StorePrivateData(); - /* Function: 0x2b */ - [todo] NTSTATUS lsa_RetrievePrivateData(); + NTSTATUS lsa_StorePrivateData( + [in] policy_handle *handle, + [in,ref] lsa_String *name, + [in,unique] lsa_DATA_BUF *val + ); + /* Function: 0x2b */ + NTSTATUS lsa_RetrievePrivateData( + [in] policy_handle *handle, + [in,ref] lsa_String *name, + [in,out,ref] lsa_DATA_BUF **val + ); /**********************/ /* Function: 0x2c */ -- cgit From dee787cb774452525fe10b13e3d5210f31dcb3eb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 11:54:49 +0200 Subject: s3-rpcclient: add LSA createsecret command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index ef3187579a..f1e28d5d8f 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1356,6 +1356,48 @@ static NTSTATUS cmd_lsa_del_priv(struct rpc_pipe_client *cli, return result; } +static NTSTATUS cmd_lsa_create_secret(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle, sec_handle; + struct lsa_String name; + + if (argc < 2) { + printf("Usage: %s name\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + status = rpccli_lsa_CreateSecret(cli, mem_ctx, + &handle, + name, + SEC_FLAG_MAXIMUM_ALLOWED, + &sec_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&sec_handle)) { + rpccli_lsa_Close(cli, mem_ctx, &sec_handle); + } + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} /* List of commands exported by this module */ @@ -1384,6 +1426,7 @@ struct cmd_set lsarpc_commands[] = { { "lsaquerytrustdominfobyname",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobyname, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a name), only works for Windows > 2k", "" }, { "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a SID)", "" }, { "getusername", RPC_RTYPE_NTSTATUS, cmd_lsa_get_username, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Get username", "" }, + { "createsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" }, { NULL } }; -- cgit From f848f4f4d3e3d3920ea1c6b94bb28ce7e7cdb73d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 11:58:10 +0200 Subject: s3-rpcclient: add LSA deletesecret command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index f1e28d5d8f..5fa30c2445 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1399,6 +1399,55 @@ static NTSTATUS cmd_lsa_create_secret(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_lsa_delete_secret(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle, sec_handle; + struct lsa_String name; + + if (argc < 2) { + printf("Usage: %s name\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + status = rpccli_lsa_OpenSecret(cli, mem_ctx, + &handle, + name, + SEC_FLAG_MAXIMUM_ALLOWED, + &sec_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpccli_lsa_DeleteObject(cli, mem_ctx, + &sec_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&sec_handle)) { + rpccli_lsa_Close(cli, mem_ctx, &sec_handle); + } + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} + /* List of commands exported by this module */ struct cmd_set lsarpc_commands[] = { @@ -1427,6 +1476,7 @@ struct cmd_set lsarpc_commands[] = { { "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a SID)", "" }, { "getusername", RPC_RTYPE_NTSTATUS, cmd_lsa_get_username, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Get username", "" }, { "createsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" }, + { "deletesecret", RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" }, { NULL } }; -- cgit From 1a862349e153250c7bad540f584bceea19738021 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 12:03:58 +0200 Subject: s3-rpcclient: add LSA querysecret command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 86 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 5fa30c2445..724ecf44d4 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1448,6 +1448,91 @@ static NTSTATUS cmd_lsa_delete_secret(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle, sec_handle; + struct lsa_String name; + struct lsa_DATA_BUF_PTR new_val; + NTTIME new_mtime = 0; + struct lsa_DATA_BUF_PTR old_val; + NTTIME old_mtime = 0; + DATA_BLOB session_key; + DATA_BLOB new_blob = data_blob_null; + DATA_BLOB old_blob = data_blob_null; + char *new_secret, *old_secret; + + if (argc < 2) { + printf("Usage: %s name\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + status = rpccli_lsa_OpenSecret(cli, mem_ctx, + &handle, + name, + SEC_FLAG_MAXIMUM_ALLOWED, + &sec_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + ZERO_STRUCT(new_val); + ZERO_STRUCT(old_val); + + status = rpccli_lsa_QuerySecret(cli, mem_ctx, + &sec_handle, + &new_val, + &new_mtime, + &old_val, + &old_mtime); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = cli_get_session_key(mem_ctx, cli, &session_key); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + if (new_val.buf) { + new_blob = data_blob_const(new_val.buf->data, new_val.buf->length); + } + if (old_val.buf) { + old_blob = data_blob_const(old_val.buf->data, old_val.buf->length); + } + + new_secret = sess_decrypt_string(mem_ctx, &new_blob, &session_key); + old_secret = sess_decrypt_string(mem_ctx, &old_blob, &session_key); + if (new_secret) { + d_printf("new secret: %s\n", new_secret); + } + if (old_secret) { + d_printf("old secret: %s\n", old_secret); + } + + done: + if (is_valid_policy_hnd(&sec_handle)) { + rpccli_lsa_Close(cli, mem_ctx, &sec_handle); + } + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} + /* List of commands exported by this module */ struct cmd_set lsarpc_commands[] = { @@ -1477,6 +1562,7 @@ struct cmd_set lsarpc_commands[] = { { "getusername", RPC_RTYPE_NTSTATUS, cmd_lsa_get_username, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Get username", "" }, { "createsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" }, { "deletesecret", RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" }, + { "querysecret", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" }, { NULL } }; -- cgit From 7194fc6a690722e5c896ee367bcba659d131fa85 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 12:56:30 +0200 Subject: s3-rpcclient: add LSA setsecret command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 71 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 724ecf44d4..5000255c84 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1533,6 +1533,76 @@ static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_lsa_set_secret(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle, sec_handle; + struct lsa_String name; + struct lsa_DATA_BUF new_val; + struct lsa_DATA_BUF old_val; + DATA_BLOB enc_key; + DATA_BLOB session_key; + + if (argc < 3) { + printf("Usage: %s name secret\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + status = rpccli_lsa_OpenSecret(cli, mem_ctx, + &handle, + name, + SEC_FLAG_MAXIMUM_ALLOWED, + &sec_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + ZERO_STRUCT(new_val); + ZERO_STRUCT(old_val); + + status = cli_get_session_key(mem_ctx, cli, &session_key); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + enc_key = sess_encrypt_string(argv[2], &session_key); + + new_val.length = enc_key.length; + new_val.size = enc_key.length; + new_val.data = enc_key.data; + + status = rpccli_lsa_SetSecret(cli, mem_ctx, + &sec_handle, + &new_val, + NULL); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&sec_handle)) { + rpccli_lsa_Close(cli, mem_ctx, &sec_handle); + } + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} + + /* List of commands exported by this module */ struct cmd_set lsarpc_commands[] = { @@ -1563,6 +1633,7 @@ struct cmd_set lsarpc_commands[] = { { "createsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" }, { "deletesecret", RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" }, { "querysecret", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" }, + { "setsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_set_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Set Secret", "" }, { NULL } }; -- cgit From 27c39a280460a1ae94bd2936535263c77729af5a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 13:30:37 +0200 Subject: s3-rpcclient: add LSA retrieveprivatedata command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 60 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 5000255c84..c4f8e2654b 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1602,6 +1602,65 @@ static NTSTATUS cmd_lsa_set_secret(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle; + struct lsa_String name; + struct lsa_DATA_BUF *val; + DATA_BLOB session_key; + DATA_BLOB blob; + char *secret; + + if (argc < 2) { + printf("Usage: %s name\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + ZERO_STRUCT(val); + + status = rpccli_lsa_RetrievePrivateData(cli, mem_ctx, + &handle, + &name, + &val); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = cli_get_session_key(mem_ctx, cli, &session_key); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + if (val) { + blob = data_blob_const(val->data, val->length); + } + + secret = sess_decrypt_string(mem_ctx, &blob, &session_key); + if (secret) { + d_printf("secret: %s\n", secret); + } + + done: + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} + /* List of commands exported by this module */ @@ -1634,6 +1693,7 @@ struct cmd_set lsarpc_commands[] = { { "deletesecret", RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" }, { "querysecret", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" }, { "setsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_set_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Set Secret", "" }, + { "retrieveprivatedata", RPC_RTYPE_NTSTATUS, cmd_lsa_retrieve_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Retrieve Private Data", "" }, { NULL } }; -- cgit From 7e9f8f0f951912943208af8cdb47c6b733b0d82c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 13:37:08 +0200 Subject: s3-rpcclient: add LSA storeprivatedata command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 56 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index c4f8e2654b..d7f8041779 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1661,6 +1661,61 @@ static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_lsa_store_private_data(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle; + struct lsa_String name; + struct lsa_DATA_BUF val; + DATA_BLOB session_key; + DATA_BLOB enc_key; + + if (argc < 3) { + printf("Usage: %s name secret\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + ZERO_STRUCT(val); + + status = cli_get_session_key(mem_ctx, cli, &session_key); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + enc_key = sess_encrypt_string(argv[2], &session_key); + + val.length = enc_key.length; + val.size = enc_key.length; + val.data = enc_key.data; + + status = rpccli_lsa_StorePrivateData(cli, mem_ctx, + &handle, + &name, + &val); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} + /* List of commands exported by this module */ @@ -1694,6 +1749,7 @@ struct cmd_set lsarpc_commands[] = { { "querysecret", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" }, { "setsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_set_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Set Secret", "" }, { "retrieveprivatedata", RPC_RTYPE_NTSTATUS, cmd_lsa_retrieve_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Retrieve Private Data", "" }, + { "storeprivatedata", RPC_RTYPE_NTSTATUS, cmd_lsa_store_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Store Private Data", "" }, { NULL } }; -- cgit From d1903cb7f2269c3eeb27ae05f734cbd8a542ee7f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 13:44:55 +0200 Subject: s3-lsa: Fix policy handle memleak and handle type check in _lsa_DeleteObject(). Guenther --- source3/rpc_server/srv_lsa_nt.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 1a6d3bae16..50bafc9349 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1304,12 +1304,22 @@ NTSTATUS _lsa_DeleteObject(pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } - status = privilege_delete_account(&info->sid); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n", - nt_errstr(status))); + switch (info->type) { + case LSA_HANDLE_ACCOUNT_TYPE: + status = privilege_delete_account(&info->sid); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n", + nt_errstr(status))); + return status; + } + break; + default: + return NT_STATUS_INVALID_HANDLE; } + close_policy_hnd(p, r->in.handle); + ZERO_STRUCTP(r->out.handle); + return status; } -- cgit From 864e8097525c2f4b05e139e78dd40dea42ab2c39 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 16:28:11 +0200 Subject: s3-lsa: also implement level 13 in lsa_QueryInfoPolicy. Guenther --- source3/rpc_server/srv_lsa_nt.c | 43 +++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 50bafc9349..c3eea6fe50 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -620,7 +620,8 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, break; } break; - case LSA_POLICY_INFO_DNS: { + case LSA_POLICY_INFO_DNS: + case LSA_POLICY_INFO_DNS_INT: { struct pdb_domain_info *dominfo; if ((pdb_capabilities() & PDB_CAP_ADS) == 0) { @@ -658,6 +659,28 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, return status; } +/*************************************************************************** + _lsa_QueryInfoPolicy2 + ***************************************************************************/ + +NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p, + struct lsa_QueryInfoPolicy2 *r2) +{ + struct lsa_QueryInfoPolicy r; + + if ((pdb_capabilities() & PDB_CAP_ADS) == 0) { + p->rng_fault_state = True; + return NT_STATUS_NOT_IMPLEMENTED; + } + + ZERO_STRUCT(r); + r.in.handle = r2->in.handle; + r.in.level = r2->in.level; + r.out.info = r2->out.info; + + return _lsa_QueryInfoPolicy(p, &r); +} + /*************************************************************************** _lsa_lookup_sids_internal ***************************************************************************/ @@ -2444,24 +2467,6 @@ NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateDat return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p, - struct lsa_QueryInfoPolicy2 *r2) -{ - struct lsa_QueryInfoPolicy r; - - if ((pdb_capabilities() & PDB_CAP_ADS) == 0) { - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; - } - - ZERO_STRUCT(r); - r.in.handle = r2->in.handle; - r.in.level = r2->in.level; - r.out.info = r2->out.info; - - return _lsa_QueryInfoPolicy(p, &r); -} - NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r) { p->rng_fault_state = True; -- cgit From 3eea254e5bfacdac1d7bb2b72863a31e0c850968 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 16:32:04 +0200 Subject: s3-lsa: add (not yet activate) level specific access checks for _lsa_QueryInfoPolicy. Guenther --- source3/rpc_server/srv_lsa_nt.c | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index c3eea6fe50..bbad9b18d2 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -505,6 +505,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, const char *name; DOM_SID *sid = NULL; union lsa_PolicyInformation *info = NULL; + uint32_t acc_required = 0; if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; @@ -513,6 +514,47 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; } + switch (r->in.level) { + case LSA_POLICY_INFO_AUDIT_LOG: + case LSA_POLICY_INFO_AUDIT_EVENTS: + acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION; + break; + case LSA_POLICY_INFO_DOMAIN: + acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION; + break; + case LSA_POLICY_INFO_PD: + acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION; + break; + case LSA_POLICY_INFO_ACCOUNT_DOMAIN: + acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION; + break; + case LSA_POLICY_INFO_ROLE: + case LSA_POLICY_INFO_REPLICA: + acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION; + break; + case LSA_POLICY_INFO_QUOTA: + acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION; + break; + case LSA_POLICY_INFO_MOD: + case LSA_POLICY_INFO_AUDIT_FULL_SET: + /* according to MS-LSAD 3.1.4.4.3 */ + return NT_STATUS_INVALID_PARAMETER; + case LSA_POLICY_INFO_AUDIT_FULL_QUERY: + acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION; + break; + case LSA_POLICY_INFO_DNS: + case LSA_POLICY_INFO_DNS_INT: + case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN: + acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION; + break; + default: + break; + } + + if (!(handle->access & acc_required)) { + /* return NT_STATUS_ACCESS_DENIED; */ + } + info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation); if (!info) { return NT_STATUS_NO_MEMORY; -- cgit From 2a26b2ac87b3a07a29ec1db128f42059ef2e4998 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 18:45:29 +0200 Subject: s3-lsa: Fix access_mask calculation for new handle in _lsa_CreateAccount(). Guenther --- source3/rpc_server/srv_lsa_nt.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index bbad9b18d2..6fb8327576 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1637,8 +1637,12 @@ NTSTATUS _lsa_GetUserName(pipes_struct *p, NTSTATUS _lsa_CreateAccount(pipes_struct *p, struct lsa_CreateAccount *r) { + NTSTATUS status; struct lsa_info *handle; struct lsa_info *info; + uint32_t acc_granted; + struct security_descriptor *psd; + uint32_t sd_size; /* find the connection policy handle. */ if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) @@ -1650,12 +1654,26 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p, /* check if the user has enough rights */ - /* - * I don't know if it's the right one. not documented. - * but guessed with rpcclient. - */ - if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) + if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) { return NT_STATUS_ACCESS_DENIED; + } + + /* map the generic bits to the lsa policy ones */ + se_map_generic(&r->in.access_mask, &lsa_account_mapping); + + status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, + &lsa_account_mapping, + r->in.sid, LSA_POLICY_ALL_ACCESS); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = access_check_object(psd, p->server_info->ptok, + NULL, 0, r->in.access_mask, + &acc_granted, "_lsa_CreateAccount"); + if (!NT_STATUS_IS_OK(status)) { + return status; + } if ( is_privileged_sid( r->in.sid ) ) return NT_STATUS_OBJECT_NAME_COLLISION; @@ -1668,7 +1686,7 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p, } info->sid = *r->in.sid; - info->access = r->in.access_mask; + info->access = acc_granted; info->type = LSA_HANDLE_ACCOUNT_TYPE; /* get a (unique) handle. open a policy on it. */ -- cgit From 3e661d4c8e1846d8f64fe029981fb7628e6211d8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 01:05:25 +0200 Subject: s3-lsa: let _lsa_Delete return NT_STATUS_NOT_SUPPORTED as w2k3 does. Guenther --- source3/rpc_server/srv_lsa_nt.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 6fb8327576..ace045cfa5 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -2431,18 +2431,22 @@ NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, return NT_STATUS_OK; } +/*************************************************************************** + _lsa_Delete + ***************************************************************************/ + +NTSTATUS _lsa_Delete(pipes_struct *p, + struct lsa_Delete *r) +{ + return NT_STATUS_NOT_SUPPORTED; +} + /* * From here on the server routines are just dummy ones to make smbd link with * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are * pulling the server stubs across one by one. */ -NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r) { p->rng_fault_state = True; -- cgit From 11bea731aebc57a63e5fbc6bc0655b50a3815539 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 15:38:40 +0200 Subject: spoolss: fill in spoolss_Create/DeletePrinterIC + rerun make samba3-idl. Guenther --- librpc/gen_ndr/cli_spoolss.c | 9 +++++ librpc/gen_ndr/cli_spoolss.h | 4 ++ librpc/gen_ndr/ndr_spoolss.c | 87 ++++++++++++++++++++++++++++++++++++++++++++ librpc/gen_ndr/spoolss.h | 11 ++++++ librpc/gen_ndr/srv_spoolss.c | 17 +++++++++ librpc/idl/spoolss.idl | 8 +++- 6 files changed, 134 insertions(+), 2 deletions(-) diff --git a/librpc/gen_ndr/cli_spoolss.c b/librpc/gen_ndr/cli_spoolss.c index 66083e6856..38031b615d 100644 --- a/librpc/gen_ndr/cli_spoolss.c +++ b/librpc/gen_ndr/cli_spoolss.c @@ -2006,12 +2006,17 @@ NTSTATUS rpccli_spoolss_DeletePort(struct rpc_pipe_client *cli, NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + struct policy_handle *gdi_handle /* [out] [ref] */, + struct spoolss_DevmodeContainer *devmode_ctr /* [in] [ref] */, WERROR *werror) { struct spoolss_CreatePrinterIC r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.devmode_ctr = devmode_ctr; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(spoolss_CreatePrinterIC, &r); @@ -2036,6 +2041,7 @@ NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli, } /* Return variables */ + *gdi_handle = *r.out.gdi_handle; /* Return result */ if (werror) { @@ -2088,12 +2094,14 @@ NTSTATUS rpccli_spoolss_PlayGDIScriptOnPrinterIC(struct rpc_pipe_client *cli, NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + struct policy_handle *gdi_handle /* [in,out] [ref] */, WERROR *werror) { struct spoolss_DeletePrinterIC r; NTSTATUS status; /* In parameters */ + r.in.gdi_handle = gdi_handle; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(spoolss_DeletePrinterIC, &r); @@ -2118,6 +2126,7 @@ NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli, } /* Return variables */ + *gdi_handle = *r.out.gdi_handle; /* Return result */ if (werror) { diff --git a/librpc/gen_ndr/cli_spoolss.h b/librpc/gen_ndr/cli_spoolss.h index baf5d61e2a..b171c69fbd 100644 --- a/librpc/gen_ndr/cli_spoolss.h +++ b/librpc/gen_ndr/cli_spoolss.h @@ -294,12 +294,16 @@ NTSTATUS rpccli_spoolss_DeletePort(struct rpc_pipe_client *cli, WERROR *werror); NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + struct policy_handle *gdi_handle /* [out] [ref] */, + struct spoolss_DevmodeContainer *devmode_ctr /* [in] [ref] */, WERROR *werror); NTSTATUS rpccli_spoolss_PlayGDIScriptOnPrinterIC(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, WERROR *werror); NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + struct policy_handle *gdi_handle /* [in,out] [ref] */, WERROR *werror); NTSTATUS rpccli_spoolss_AddPrinterConnection(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index a1be2fd92c..b5d9f1739c 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -23702,8 +23702,20 @@ _PUBLIC_ void ndr_print_spoolss_DeletePort(struct ndr_print *ndr, const char *na static enum ndr_err_code ndr_push_spoolss_CreatePrinterIC(struct ndr_push *ndr, int flags, const struct spoolss_CreatePrinterIC *r) { if (flags & NDR_IN) { + if (r->in.handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle)); + if (r->in.devmode_ctr == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_spoolss_DevmodeContainer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.devmode_ctr)); } if (flags & NDR_OUT) { + if (r->out.gdi_handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle)); NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -23711,9 +23723,37 @@ static enum ndr_err_code ndr_push_spoolss_CreatePrinterIC(struct ndr_push *ndr, static enum ndr_err_code ndr_pull_spoolss_CreatePrinterIC(struct ndr_pull *ndr, int flags, struct spoolss_CreatePrinterIC *r) { + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_gdi_handle_0; + TALLOC_CTX *_mem_save_devmode_ctr_0; if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.handle); + } + _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.devmode_ctr); + } + _mem_save_devmode_ctr_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.devmode_ctr, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_spoolss_DevmodeContainer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.devmode_ctr)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_ctr_0, LIBNDR_FLAG_REF_ALLOC); + NDR_PULL_ALLOC(ndr, r->out.gdi_handle); + ZERO_STRUCTP(r->out.gdi_handle); } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.gdi_handle); + } + _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.gdi_handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -23729,11 +23769,23 @@ _PUBLIC_ void ndr_print_spoolss_CreatePrinterIC(struct ndr_print *ndr, const cha if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "spoolss_CreatePrinterIC"); ndr->depth++; + ndr_print_ptr(ndr, "handle", r->in.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->in.handle); + ndr->depth--; + ndr_print_ptr(ndr, "devmode_ctr", r->in.devmode_ctr); + ndr->depth++; + ndr_print_spoolss_DevmodeContainer(ndr, "devmode_ctr", r->in.devmode_ctr); + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "spoolss_CreatePrinterIC"); ndr->depth++; + ndr_print_ptr(ndr, "gdi_handle", r->out.gdi_handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "gdi_handle", r->out.gdi_handle); + ndr->depth--; ndr_print_WERROR(ndr, "result", r->out.result); ndr->depth--; } @@ -23784,8 +23836,16 @@ _PUBLIC_ void ndr_print_spoolss_PlayGDIScriptOnPrinterIC(struct ndr_print *ndr, static enum ndr_err_code ndr_push_spoolss_DeletePrinterIC(struct ndr_push *ndr, int flags, const struct spoolss_DeletePrinterIC *r) { if (flags & NDR_IN) { + if (r->in.gdi_handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.gdi_handle)); } if (flags & NDR_OUT) { + if (r->out.gdi_handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle)); NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -23793,9 +23853,28 @@ static enum ndr_err_code ndr_push_spoolss_DeletePrinterIC(struct ndr_push *ndr, static enum ndr_err_code ndr_pull_spoolss_DeletePrinterIC(struct ndr_pull *ndr, int flags, struct spoolss_DeletePrinterIC *r) { + TALLOC_CTX *_mem_save_gdi_handle_0; if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.gdi_handle); + } + _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.gdi_handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.gdi_handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC); + NDR_PULL_ALLOC(ndr, r->out.gdi_handle); + *r->out.gdi_handle = *r->in.gdi_handle; } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.gdi_handle); + } + _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.gdi_handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -23811,11 +23890,19 @@ _PUBLIC_ void ndr_print_spoolss_DeletePrinterIC(struct ndr_print *ndr, const cha if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "spoolss_DeletePrinterIC"); ndr->depth++; + ndr_print_ptr(ndr, "gdi_handle", r->in.gdi_handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "gdi_handle", r->in.gdi_handle); + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "spoolss_DeletePrinterIC"); ndr->depth++; + ndr_print_ptr(ndr, "gdi_handle", r->out.gdi_handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "gdi_handle", r->out.gdi_handle); + ndr->depth--; ndr_print_WERROR(ndr, "result", r->out.result); ndr->depth--; } diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 9446193863..2575c4d082 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -2516,6 +2516,12 @@ struct spoolss_DeletePort { struct spoolss_CreatePrinterIC { struct { + struct policy_handle *handle;/* [ref] */ + struct spoolss_DevmodeContainer *devmode_ctr;/* [ref] */ + } in; + + struct { + struct policy_handle *gdi_handle;/* [ref] */ WERROR result; } out; @@ -2532,6 +2538,11 @@ struct spoolss_PlayGDIScriptOnPrinterIC { struct spoolss_DeletePrinterIC { struct { + struct policy_handle *gdi_handle;/* [ref] */ + } in; + + struct { + struct policy_handle *gdi_handle;/* [ref] */ WERROR result; } out; diff --git a/librpc/gen_ndr/srv_spoolss.c b/librpc/gen_ndr/srv_spoolss.c index 41a79b4a79..ae99f098a6 100644 --- a/librpc/gen_ndr/srv_spoolss.c +++ b/librpc/gen_ndr/srv_spoolss.c @@ -3245,6 +3245,13 @@ static bool api_spoolss_CreatePrinterIC(pipes_struct *p) NDR_PRINT_IN_DEBUG(spoolss_CreatePrinterIC, r); } + ZERO_STRUCT(r->out); + r->out.gdi_handle = talloc_zero(r, struct policy_handle); + if (r->out.gdi_handle == NULL) { + talloc_free(r); + return false; + } + r->out.result = _spoolss_CreatePrinterIC(p, r); if (p->rng_fault_state) { @@ -3391,6 +3398,8 @@ static bool api_spoolss_DeletePrinterIC(pipes_struct *p) NDR_PRINT_IN_DEBUG(spoolss_DeletePrinterIC, r); } + ZERO_STRUCT(r->out); + r->out.gdi_handle = r->in.gdi_handle; r->out.result = _spoolss_DeletePrinterIC(p, r); if (p->rng_fault_state) { @@ -8068,6 +8077,12 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, case NDR_SPOOLSS_CREATEPRINTERIC: { struct spoolss_CreatePrinterIC *r = (struct spoolss_CreatePrinterIC *)_r; + ZERO_STRUCT(r->out); + r->out.gdi_handle = talloc_zero(mem_ctx, struct policy_handle); + if (r->out.gdi_handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + r->out.result = _spoolss_CreatePrinterIC(cli->pipes_struct, r); return NT_STATUS_OK; } @@ -8080,6 +8095,8 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, case NDR_SPOOLSS_DELETEPRINTERIC: { struct spoolss_DeletePrinterIC *r = (struct spoolss_DeletePrinterIC *)_r; + ZERO_STRUCT(r->out); + r->out.gdi_handle = r->in.gdi_handle; r->out.result = _spoolss_DeletePrinterIC(cli->pipes_struct, r); return NT_STATUS_OK; } diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index f37424634d..acfb54f923 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1683,7 +1683,10 @@ import "misc.idl", "security.idl", "winreg.idl"; /******************/ /* Function: 0x28 */ - [todo] WERROR spoolss_CreatePrinterIC( + WERROR spoolss_CreatePrinterIC( + [in,ref] policy_handle *handle, + [out,ref] policy_handle *gdi_handle, + [in,ref] spoolss_DevmodeContainer *devmode_ctr ); /******************/ @@ -1693,7 +1696,8 @@ import "misc.idl", "security.idl", "winreg.idl"; /******************/ /* Function: 0x2a */ - [todo] WERROR spoolss_DeletePrinterIC( + WERROR spoolss_DeletePrinterIC( + [in,out,ref] policy_handle *gdi_handle ); /******************/ -- cgit From ffbcf3b491293db92141f7936e3fefc81066e730 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 15:39:40 +0200 Subject: s3-rpcclient: add createprinteric command. Guenther --- source3/rpcclient/cmd_spoolss.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index cbff69ff17..48f9df3cac 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -3430,6 +3430,48 @@ static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli, return werror; } +static WERROR cmd_spoolss_create_printer_ic(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + WERROR result; + NTSTATUS status; + struct policy_handle handle, gdi_handle; + const char *printername; + struct spoolss_DevmodeContainer devmode_ctr; + + RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); + + result = rpccli_spoolss_openprinter_ex(cli, mem_ctx, + printername, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!W_ERROR_IS_OK(result)) { + return result; + } + + ZERO_STRUCT(devmode_ctr); + + status = rpccli_spoolss_CreatePrinterIC(cli, mem_ctx, + &handle, + &gdi_handle, + &devmode_ctr, + &result); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&gdi_handle)) { + rpccli_spoolss_DeletePrinterIC(cli, mem_ctx, &gdi_handle, NULL); + } + if (is_valid_policy_hnd(&handle)) { + rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); + } + + return result; +} + /* List of commands exported by this module */ struct cmd_set spoolss_commands[] = { @@ -3469,6 +3511,7 @@ struct cmd_set spoolss_commands[] = { { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" }, { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" }, { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" }, + { "createprinteric", RPC_RTYPE_WERROR, NULL, cmd_spoolss_create_printer_ic, &ndr_table_spoolss.syntax_id, NULL, "Create Printer IC", "" }, { NULL } }; -- cgit From f394fa7766d394f30d35da4191a9ec7b09693a9c Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Sat, 18 Jul 2009 14:07:33 +0800 Subject: s3: add failure check. Signed-off-by: Bo Yang --- nsswitch/pam_winbind.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c index f692316fc6..4e84574d25 100644 --- a/nsswitch/pam_winbind.c +++ b/nsswitch/pam_winbind.c @@ -2298,9 +2298,12 @@ static char* winbind_upn_to_username(struct pwb_context *ctx, } name = talloc_strdup(ctx, upn); + if (!name) { + return NULL; + } if ((p = strchr(name, '@')) != NULL) { *p = 0; - domain = talloc_strdup(ctx, p + 1); + domain = p + 1; } /* Convert the UPN to a SID */ -- cgit From 1a7a8d43308e73d6136ba96e07b10519b4713306 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 16:47:48 +0200 Subject: spoolss: fill in some unknowns in spoolss_OSVersion and spoolss_OSVersionEx. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 29 +++++++++++++++++++---------- librpc/gen_ndr/spoolss.h | 11 +++++++---- librpc/idl/spoolss.idl | 11 +++++++---- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index b5d9f1739c..fedebb2d56 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -14464,7 +14464,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_OSVersion(struct ndr_pull *ndr, int NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->major)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->minor)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->build)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->platform_id)); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); @@ -14490,7 +14490,7 @@ _PUBLIC_ void ndr_print_spoolss_OSVersion(struct ndr_print *ndr, const char *nam ndr_print_uint32(ndr, "major", r->major); ndr_print_uint32(ndr, "minor", r->minor); ndr_print_uint32(ndr, "build", r->build); - ndr_print_uint32(ndr, "unknown", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->unknown); + ndr_print_uint32(ndr, "platform_id", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->platform_id); ndr_print_string(ndr, "extra_string", r->extra_string); ndr->depth--; } @@ -14520,8 +14520,11 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_OSVersionEx(struct ndr_push *ndr, in } ndr->flags = _flags_save_string; } - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown2)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown3)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->service_pack_major)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->service_pack_minor)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->suite_mask)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->product_type)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->reserved)); } if (ndr_flags & NDR_BUFFERS) { } @@ -14536,7 +14539,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_OSVersionEx(struct ndr_pull *ndr, in NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->major)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->minor)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->build)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown1)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->platform_id)); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); @@ -14548,8 +14551,11 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_OSVersionEx(struct ndr_pull *ndr, in } ndr->flags = _flags_save_string; } - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown2)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown3)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->service_pack_major)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->service_pack_minor)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->suite_mask)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->product_type)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->reserved)); } if (ndr_flags & NDR_BUFFERS) { } @@ -14564,10 +14570,13 @@ _PUBLIC_ void ndr_print_spoolss_OSVersionEx(struct ndr_print *ndr, const char *n ndr_print_uint32(ndr, "major", r->major); ndr_print_uint32(ndr, "minor", r->minor); ndr_print_uint32(ndr, "build", r->build); - ndr_print_uint32(ndr, "unknown1", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->unknown1); + ndr_print_uint32(ndr, "platform_id", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->platform_id); ndr_print_string(ndr, "extra_string", r->extra_string); - ndr_print_uint32(ndr, "unknown2", r->unknown2); - ndr_print_uint32(ndr, "unknown3", r->unknown3); + ndr_print_uint16(ndr, "service_pack_major", r->service_pack_major); + ndr_print_uint16(ndr, "service_pack_minor", r->service_pack_minor); + ndr_print_uint16(ndr, "suite_mask", r->suite_mask); + ndr_print_uint8(ndr, "product_type", r->product_type); + ndr_print_uint8(ndr, "reserved", r->reserved); ndr->depth--; } diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 2575c4d082..1a9d393e09 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -1058,7 +1058,7 @@ struct spoolss_OSVersion { uint32_t major; uint32_t minor; uint32_t build; - uint32_t unknown;/* [value(2)] */ + uint32_t platform_id;/* [value(2)] */ const char * extra_string;/* [subcontext_size(256),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */ }/* [gensize,public] */; @@ -1067,10 +1067,13 @@ struct spoolss_OSVersionEx { uint32_t major; uint32_t minor; uint32_t build; - uint32_t unknown1;/* [value(2)] */ + uint32_t platform_id;/* [value(2)] */ const char * extra_string;/* [subcontext_size(256),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */ - uint32_t unknown2; - uint32_t unknown3; + uint16_t service_pack_major; + uint16_t service_pack_minor; + uint16_t suite_mask; + uint8_t product_type; + uint8_t reserved; }/* [gensize,public] */; union spoolss_PrinterData { diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index acfb54f923..0c68dffcd1 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1311,7 +1311,7 @@ import "misc.idl", "security.idl", "winreg.idl"; uint32 major; uint32 minor; uint32 build; - [value(2)] uint32 unknown; + [value(2)] uint32 platform_id; [subcontext(0),subcontext_size(256)] nstring extra_string; } spoolss_OSVersion; @@ -1320,10 +1320,13 @@ import "misc.idl", "security.idl", "winreg.idl"; uint32 major; uint32 minor; uint32 build; - [value(2)] uint32 unknown1; + [value(2)] uint32 platform_id; [subcontext(0),subcontext_size(256)] nstring extra_string; - uint32 unknown2;/* service pack number? I saw 0 from w2k3 and 1 from winxp sp1*/ - uint32 unknown3;/* hmm? w2k3: 131346(0x20112) winxp sp1: 503382272 0x1E010100 */ + uint16 service_pack_major; + uint16 service_pack_minor; + uint16 suite_mask; + uint8 product_type; + uint8 reserved; } spoolss_OSVersionEx; typedef [nodiscriminant,public,gensize] union { -- cgit From 3b44c0c21ee150c1bb13dcfcdbdf25f0479cc400 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 17:16:44 +0200 Subject: s4-spoolss: fix the build after OsVersion changes. Guenther --- source4/ntptr/simple_ldb/ntptr_simple_ldb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c index 4ebbaaeffc..601f7902df 100644 --- a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c +++ b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c @@ -192,9 +192,12 @@ static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC os_ex.major = server_info->version_major; os_ex.minor = server_info->version_minor; os_ex.build = server_info->version_build; - os_ex.extra_string = ""; - os_ex.unknown2 = 0; - os_ex.unknown3 = 0; + os_ex.extra_string = ""; + os_ex.service_pack_major= 0; + os_ex.service_pack_minor= 0; + os_ex.suite_mask = 0; + os_ex.product_type = 0; + os_ex.reserved = 0; ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(server->ntptr->lp_ctx), &os_ex, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersionEx); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { -- cgit From 33251da8611ddc98c3ae73d62601218e5b784e63 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 17 Jul 2009 22:40:24 +0200 Subject: 3.4 is released... --- Roadmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Roadmap b/Roadmap index 1132f6391c..c5b8a4d115 100644 --- a/Roadmap +++ b/Roadmap @@ -12,7 +12,7 @@ are in progress: Samba-3.0.x This release turned into maintenance mode since we released 3.2. -Samba-3.2.x This is the current stable Samba 3 release intended +Samba-3.4.x This is the current stable Samba 3 release intended for all Samba production server. Samba-4 Danger Will Robinson, a big code clean up with major -- cgit From 6a9e0039100b57f9626e87defec6720c476b9789 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 17:36:26 -0700 Subject: Fix bug #6564 - SetPrinter fails (panics) as non root. Missing become_root()/unbecome_root() around reload_services. Jeremy. --- source3/rpc_server/srv_spoolss_nt.c | 4 ++++ source3/smbd/server.c | 1 + 2 files changed, 5 insertions(+) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 48ac103667..9dc1a26e3b 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -309,7 +309,9 @@ static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const c return WERR_BADFID; /* What to return here? */ /* go ahead and re-read the services immediately */ + become_root(); reload_services(false); + unbecome_root(); if ( lp_servicenumber( sharename ) < 0 ) return WERR_ACCESS_DENIED; @@ -6034,7 +6036,9 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV } /* reload our services immediately */ + become_root(); reload_services(false); + unbecome_root(); numlines = 0; /* Get lines and convert them back to dos-codepage */ diff --git a/source3/smbd/server.c b/source3/smbd/server.c index a1dec0327c..4b1c803d75 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -94,6 +94,7 @@ static void smb_conf_updated(struct messaging_context *msg, { DEBUG(10,("smb_conf_updated: Got message saying smb.conf was " "updated. Reloading.\n")); + change_to_root_user(); reload_services(False); } -- cgit From 55b4231c773ef17b8e628f33d6c3c9d5335df9da Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 17:57:48 -0700 Subject: Move the initialization of smbd_server_conn from smbd/process, after the accept and fork, to smbd_init_globals(), so it's done immediately on server startup. This is needed as some messages are sent to all active smbd processes (including the master listening daemon). If it gets a message that forces it to scan it's current connections (ie. conn_find()) then it discovers that sconn->smb1.tcons.Connections dereferences null (as sconn == NULL in the parent) and crashes. Yes, I could fix all cases where sconn is used and explicitly check for NULL but this fix is easier. It means that the smbd_event_context() is initialized in the master daemon and then re-initialized after fork, but that should be being done correctly in every fork call anyway. Without this change the previous fix 6a9e0039100b57f9626e87defec6720c476b9789 still panics in the reproducible test case for bug 6564, as this is one case where such a message (MSG_SMB_CONF_UPDATED) is sent to the parent. Metze please check. This change passes valgrind. Jeremy. --- source3/smbd/globals.c | 5 +++++ source3/smbd/process.c | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c index 15550ed455..317304a86d 100644 --- a/source3/smbd/globals.c +++ b/source3/smbd/globals.c @@ -153,4 +153,9 @@ void smbd_init_globals(void) ZERO_STRUCT(conn_ctx_stack); ZERO_STRUCT(sec_ctx_stack); + + smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection); + if (!smbd_server_conn) { + exit_server("failed to create smbd_server_connection"); + } } diff --git a/source3/smbd/process.c b/source3/smbd/process.c index b26bc150db..c2065caf79 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -2015,11 +2015,6 @@ void smbd_process(void) TALLOC_CTX *frame = talloc_stackframe(); char remaddr[INET6_ADDRSTRLEN]; - smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection); - if (!smbd_server_conn) { - exit_server("failed to create smbd_server_connection"); - } - if (lp_maxprotocol() == PROTOCOL_SMB2 && lp_security() != SEC_SHARE) { smbd_server_conn->allow_smb2 = true; -- cgit From eba2eb45e208e6b3091c01ff1d40fd966e72a044 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 18:05:10 -0700 Subject: Fix a typo reading uninitialized memory. Caught by valgrind. Jeremy. --- source3/lib/system.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source3/lib/system.c b/source3/lib/system.c index ffc236e93b..6a4f5d5413 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -458,8 +458,6 @@ static struct timespec calc_create_time_stat_ex(const struct stat_ex *st) static void get_create_timespec(const struct stat *pst, struct stat_ex *dst) { - struct timespec ret; - if (S_ISDIR(pst->st_mode) && lp_fake_dir_create_times()) { dst->st_ex_btime.tv_sec = 315493200L; /* 1/1/1980 */ dst->st_ex_btime.tv_nsec = 0; @@ -483,7 +481,7 @@ static void get_create_timespec(const struct stat *pst, struct stat_ex *dst) /* Deal with systems that don't initialize birthtime correctly. * Pointed out by SATOH Fumiyasu . */ - if (null_timespec(ret)) { + if (null_timespec(dst->st_ex_btime)) { dst->st_ex_btime = calc_create_time_stat(pst); dst->st_ex_calculated_birthtime = true; } -- cgit From 7254898bc760984357f068926cb4504c154d5cae Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 21:26:16 -0700 Subject: Fix coverity CID 931. This check is redundent as smb_fname can never be null in this function. Jeremy. --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 06536f9e21..561c18a29d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7244,7 +7244,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, case SMB_SET_FILE_UNIX_HLINK: { - if (fsp || smb_fname == NULL) { + if (fsp) { /* We must have a pathname for this. */ return NT_STATUS_INVALID_LEVEL; } -- cgit From d654782806af37ba0d249f695ebecaad2a6ad3a7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 21:29:28 -0700 Subject: Fix coverity CID 930. Pointer check can never be null here. Jeremy --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 561c18a29d..cb76deb90a 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4806,7 +4806,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, /* We know this name is ok, it's already passed the checks. */ - } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) { + } else if(fsp->is_directory || fsp->fh->fd == -1) { /* * This is actually a QFILEINFO on a directory * handle (returned from an NT SMB). NT5.0 seems -- cgit From 3036a9c7c12d382b925a1f0e2d6265a3817bd3c4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 21:36:55 -0700 Subject: Fix Coverity CID 929. Potential NULL deref after code refactoring. Jeremy. --- source3/smbd/trans2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index cb76deb90a..7a0feea291 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4649,6 +4649,11 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, uint32 lock_pid; enum brl_type lock_type; + /* We need an open file with a real fd for this. */ + if (!fsp || fsp->is_directory || fsp->fh->fd == -1) { + return NT_STATUS_INVALID_LEVEL; + } + if (lock_data_count != POSIX_LOCK_DATA_SIZE) { return NT_STATUS_INVALID_PARAMETER; } -- cgit From 0bd13fda76d8cb4f345411b847d5be233e12bcc0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 21:40:23 -0700 Subject: Fix Coverity CID 928. Removed check as this can never be null. Jeremy. --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 7a0feea291..122114c24f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4088,7 +4088,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, file_size = get_file_size_stat(&sbuf); } - if (fsp && fsp->fh) { + if (fsp) { pos = fsp->fh->position_information; } -- cgit From 0259a303f4cd69b2db0b059335421f8d0dbc74f5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 21:50:33 -0700 Subject: Fix Coverity CIDs 887, 888. Don't pass NULL's to functions that deref them. Jeremy. --- source3/passdb/pdb_wbc_sam.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c index 2161d2ff5c..df80411a7a 100644 --- a/source3/passdb/pdb_wbc_sam.c +++ b/source3/passdb/pdb_wbc_sam.c @@ -316,13 +316,12 @@ static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map const char *name) { NTSTATUS result = NT_STATUS_OK; - char *user_name = NULL; - char *domain = NULL; + const char *domain = ""; DOM_SID sid; gid_t gid; enum lsa_SidType name_type; - if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) { + if (!winbind_lookup_name(domain, name, &sid, &name_type)) { result = NT_STATUS_NO_SUCH_GROUP; goto done; } @@ -340,7 +339,7 @@ static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map goto done; } - if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) { + if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { result = NT_STATUS_NO_SUCH_GROUP; goto done; } -- cgit From 8c5aff207d25764dd457050c2e5975b4b42c917f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Jul 2009 10:37:59 +0200 Subject: ldb: Display SHLD_FLAGS when building. --- source4/lib/ldb/rules.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/lib/ldb/rules.mk b/source4/lib/ldb/rules.mk index 639271b76d..0598f8039b 100644 --- a/source4/lib/ldb/rules.mk +++ b/source4/lib/ldb/rules.mk @@ -19,6 +19,7 @@ ctags: showflags:: @echo 'ldb will be compiled with flags:' @echo ' CFLAGS = $(CFLAGS)' + @echo ' SHLD_FLAGS = $(SHLD_FLAGS)' @echo ' LIBS = $(LIBS)' distclean:: -- cgit From d356669492912ad97d031694123b628a9307c3bd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Jul 2009 16:11:21 +0200 Subject: Remove pyldb_util and simply duplicate the 5-line function it contains, rather than creating a separate shared library for it. --- source4/lib/ldb/ldb.mk | 7 ++----- source4/lib/ldb/pyldb.c | 10 ++++++++++ source4/lib/ldb/pyldb.h | 1 - source4/lib/ldb/pyldb_util.c | 39 --------------------------------------- source4/lib/ldb/python.mk | 8 -------- source4/scripting/python/pyglue.c | 9 +++++++++ 6 files changed, 21 insertions(+), 53 deletions(-) delete mode 100644 source4/lib/ldb/pyldb_util.c diff --git a/source4/lib/ldb/ldb.mk b/source4/lib/ldb/ldb.mk index a9a6dad46d..4234fcc311 100644 --- a/source4/lib/ldb/ldb.mk +++ b/source4/lib/ldb/ldb.mk @@ -67,11 +67,8 @@ build-python:: ldb.$(SHLIBEXT) pyldb.o: $(ldbdir)/pyldb.c $(CC) $(PICFLAG) -c $(ldbdir)/pyldb.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags` -pyldb_util.o: $(ldbdir)/pyldb_util.c - $(CC) $(PICFLAG) -c $(ldbdir)/pyldb_util.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags` - -ldb.$(SHLIBEXT): pyldb.o pyldb_util.o - $(SHLD) $(SHLD_FLAGS) -o ldb.$(SHLIBEXT) pyldb.o pyldb_util.o $(LIB_FLAGS) `$(PYTHON_CONFIG) --ldflags` +ldb.$(SHLIBEXT): pyldb.o + $(SHLD) $(SHLD_FLAGS) -o ldb.$(SHLIBEXT) pyldb.o $(LIB_FLAGS) `$(PYTHON_CONFIG) --ldflags` install-python:: build-python mkdir -p $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"` diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index 2e0f4fdf36..bcca70eb82 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -41,6 +41,16 @@ typedef intargfunc ssizeargfunc; #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None #endif +static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) +{ + if (ret == LDB_ERR_PYTHON_EXCEPTION) + return; /* Python exception should already be set, just keep that */ + + PyErr_SetObject(error, + Py_BuildValue(discard_const_p(char, "(i,s)"), ret, + ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); +} + static PyObject *PyExc_LdbError; PyAPI_DATA(PyTypeObject) PyLdbMessage; diff --git a/source4/lib/ldb/pyldb.h b/source4/lib/ldb/pyldb.h index e0e0d2af69..a0954158bd 100644 --- a/source4/lib/ldb/pyldb.h +++ b/source4/lib/ldb/pyldb.h @@ -85,7 +85,6 @@ typedef struct { PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *); #define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree -void PyErr_SetLdbError(PyObject *exctype, int ret, struct ldb_context *ldb_ctx); #define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) \ if (ret != LDB_SUCCESS) { \ PyErr_SetLdbError(err, ret, ldb); \ diff --git a/source4/lib/ldb/pyldb_util.c b/source4/lib/ldb/pyldb_util.c deleted file mode 100644 index 84183e89de..0000000000 --- a/source4/lib/ldb/pyldb_util.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - interface to ldb. - - Copyright (C) 2009 Jelmer Vernooij - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include -#include "pyldb.h" -#include - -void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) -{ - if (ret == LDB_ERR_PYTHON_EXCEPTION) - return; /* Python exception should already be set, just keep that */ - - PyErr_SetObject(error, - Py_BuildValue(discard_const_p(char, "(i,s)"), ret, - ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); -} diff --git a/source4/lib/ldb/python.mk b/source4/lib/ldb/python.mk index e08c150aaf..dbc2eb27eb 100644 --- a/source4/lib/ldb/python.mk +++ b/source4/lib/ldb/python.mk @@ -1,14 +1,6 @@ [PYTHON::pyldb] LIBRARY_REALNAME = ldb.$(SHLIBEXT) PUBLIC_DEPENDENCIES = LIBLDB PYTALLOC -PRIVATE_DEPENDENCIES = pyldb_util pyldb_OBJ_FILES = $(ldbsrcdir)/pyldb.o $(pyldb_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/include - -[SUBSYSTEM::pyldb_util] -PUBLIC_DEPENDENCIES = LIBPYTHON -PRIVATE_DEPENDENCIES = LIBLDB - -pyldb_util_OBJ_FILES = $(ldbsrcdir)/pyldb_util.o -$(pyldb_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/include diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c index c6b731ce8b..0869d2feac 100644 --- a/source4/scripting/python/pyglue.c +++ b/source4/scripting/python/pyglue.c @@ -46,6 +46,15 @@ } */\ ldb = PyLdb_AsLdbContext(py_ldb); +static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) +{ + if (ret == LDB_ERR_PYTHON_EXCEPTION) + return; /* Python exception should already be set, just keep that */ + + PyErr_SetObject(error, + Py_BuildValue(discard_const_p(char, "(i,s)"), ret, + ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); +} static PyObject *py_ldb_get_exception(void) { -- cgit From d884fcf9a0e52c6ea6707c57c30f0e3dfea9a345 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Jul 2009 18:28:57 +0200 Subject: Actually fill in ldb modules directory. --- source4/lib/ldb/ldb.pc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/lib/ldb/ldb.pc.in b/source4/lib/ldb/ldb.pc.in index b7e4c85844..01482f6bfb 100644 --- a/source4/lib/ldb/ldb.pc.in +++ b/source4/lib/ldb/ldb.pc.in @@ -2,7 +2,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ -modulesdir=@modulesdir@ +modulesdir=@LDB_MODULESDIR@ Name: ldb Description: An LDAP-like embedded database -- cgit From 7883897b8d4e5993e636d3cde8bad509ee272fcb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Jul 2009 18:39:20 +0200 Subject: python: Set right ldb modules directory when using system ldb. --- source4/scripting/python/samba/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index e3ebc4a637..131d1a3ac6 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -73,6 +73,8 @@ class Ldb(ldb.Ldb): self.set_modules_dir(modules_dir) elif default_ldb_modules_dir is not None: self.set_modules_dir(default_ldb_modules_dir) + elif lp is not None: + self.set_modules_dir(os.path.join(lp.get("modules dir"), "ldb")) if credentials is not None: self.set_credentials(credentials) -- cgit From 27087e6a878aa216d73ea629535be49fca10315f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Jul 2009 20:04:11 +0200 Subject: VFS examples: Update copy of config.{guess,sub}. --- examples/VFS/config.guess | 152 ++++++++++++++++++++++++++++------ examples/VFS/config.sub | 205 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 282 insertions(+), 75 deletions(-) diff --git a/examples/VFS/config.guess b/examples/VFS/config.guess index 600580b1aa..da83314608 100755 --- a/examples/VFS/config.guess +++ b/examples/VFS/config.guess @@ -1,13 +1,14 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. -timestamp='2005-09-19' +timestamp='2009-04-27' # This file 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 +# 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 @@ -16,7 +17,9 @@ timestamp='2005-09-19' # 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 . +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -53,8 +56,8 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -104,7 +107,7 @@ set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; @@ -158,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched @@ -204,8 +208,11 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} @@ -317,14 +324,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize @@ -525,7 +548,7 @@ EOF echo rs6000-ibm-aix3.2 fi exit ;; - *:AIX:*:[45]) + *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 @@ -762,12 +785,19 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; - i*:MINGW*:*) + *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) @@ -777,9 +807,18 @@ EOF i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd | genuineintel) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; @@ -813,6 +852,16 @@ EOF echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) @@ -849,7 +898,11 @@ EOF #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) @@ -868,7 +921,11 @@ EOF #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) @@ -894,6 +951,9 @@ EOF if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in @@ -917,9 +977,15 @@ EOF sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent @@ -938,9 +1004,6 @@ EOF a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. @@ -962,7 +1025,7 @@ EOF LIBC=gnulibc1 # endif #else - #ifdef __INTEL_COMPILER + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout @@ -972,7 +1035,11 @@ EOF LIBC=dietlibc #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit @@ -1051,8 +1118,11 @@ EOF pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 @@ -1090,6 +1160,16 @@ EOF 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; @@ -1165,6 +1245,9 @@ EOF BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; @@ -1174,6 +1257,15 @@ EOF SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; @@ -1261,6 +1353,12 @@ EOF i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 @@ -1421,9 +1519,9 @@ This script, last modified $timestamp, has failed to recognize the operating system you are using. It is advised that you download the most up to date version of the config scripts from - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD and - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD If the version you run ($0) is already up to date, please send the following data and any information you think might be diff --git a/examples/VFS/config.sub b/examples/VFS/config.sub index 23cd6fd75c..a39437d015 100755 --- a/examples/VFS/config.sub +++ b/examples/VFS/config.sub @@ -1,9 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. -timestamp='2005-07-08' +timestamp='2009-04-17' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -11,7 +12,7 @@ timestamp='2005-07-08' # # This file 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 +# 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, @@ -20,7 +21,9 @@ timestamp='2005-07-08' # 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 . +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -69,8 +72,8 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -117,8 +120,10 @@ esac # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -169,6 +174,10 @@ case $os in -hiux*) os=-hiuxwe2 ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -185,6 +194,10 @@ case $os in # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -229,20 +242,24 @@ case $basic_machine in | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ + | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ - | mips64vr | mips64vrel \ + | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ @@ -255,26 +272,26 @@ case $basic_machine in | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ - | ms1 \ + | moxie \ + | mt \ | msp430 \ + | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m32c) + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) @@ -284,6 +301,9 @@ case $basic_machine in ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; + ms1) + basic_machine=mt-unknown + ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and @@ -303,25 +323,28 @@ case $basic_machine in | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ + | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ + | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ @@ -334,30 +357,33 @@ case $basic_machine in | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ - | ms1-* \ + | mt-* \ | msp430-* \ + | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ | ymp-* \ - | z8k-*) + | z8k-* | z80-*) ;; - m32c-*) + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. @@ -421,6 +447,10 @@ case $basic_machine in basic_machine=m68k-apollo os=-bsd ;; + aros) + basic_machine=i386-pc + os=-aros + ;; aux) basic_machine=m68k-apple os=-aux @@ -429,10 +459,22 @@ case $basic_machine in basic_machine=ns32k-sequent os=-dynix ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; c90) basic_machine=c90-cray os=-unicos ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; convex-c1) basic_machine=c1-convex os=-bsd @@ -461,8 +503,8 @@ case $basic_machine in basic_machine=craynv-cray os=-unicosmp ;; - cr16c) - basic_machine=cr16c-unknown + cr16) + basic_machine=cr16-unknown os=-elf ;; crds | unos) @@ -500,6 +542,10 @@ case $basic_machine in basic_machine=m88k-motorola os=-sysv3 ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp @@ -654,6 +700,14 @@ case $basic_machine in basic_machine=m68k-isi os=-sysv ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; m88k-omron*) basic_machine=m88k-omron ;; @@ -669,6 +723,10 @@ case $basic_machine in basic_machine=i386-pc os=-mingw32 ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; miniframe) basic_machine=m68000-convergent ;; @@ -694,6 +752,9 @@ case $basic_machine in basic_machine=i386-pc os=-msdos ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; mvs) basic_machine=i370-ibm os=-mvs @@ -792,6 +853,14 @@ case $basic_machine in basic_machine=i860-intel os=-osf ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; pbd) basic_machine=sparc-tti ;; @@ -801,6 +870,12 @@ case $basic_machine in pc532 | pc532-*) basic_machine=ns32k-pc532 ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; @@ -857,6 +932,10 @@ case $basic_machine in basic_machine=i586-unknown os=-pw32 ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; rom68k) basic_machine=m68k-rom68k os=-coff @@ -883,6 +962,10 @@ case $basic_machine in sb1el) basic_machine=mipsisa64sb1el-unknown ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; sei) basic_machine=mips-sei os=-seiux @@ -894,6 +977,9 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sh5el) + basic_machine=sh5le-unknown + ;; sh64) basic_machine=sh64-unknown ;; @@ -983,6 +1069,10 @@ case $basic_machine in basic_machine=tic6x-unknown os=-coff ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; tx39) basic_machine=mipstx39-unknown ;; @@ -1058,6 +1148,10 @@ case $basic_machine in basic_machine=z8k-unknown os=-sim ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -1096,10 +1190,10 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sparc | sparcv8 | sparcv9 | sparcv9b) + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) @@ -1168,25 +1262,28 @@ case $os in -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ + | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ + | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1316,6 +1413,9 @@ case $os in -zvmoe) os=-zvmoe ;; + -dicos*) + os=-dicos + ;; -none) ;; *) @@ -1338,6 +1438,12 @@ else # system, and we'll never get to this point. case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; *-acorn) os=-riscix1.2 ;; @@ -1347,9 +1453,9 @@ case $basic_machine in arm*-semi) os=-aout ;; - c4x-* | tic4x-*) - os=-coff - ;; + c4x-* | tic4x-*) + os=-coff + ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 @@ -1375,6 +1481,9 @@ case $basic_machine in m68*-cisco) os=-aout ;; + mep-*) + os=-elf + ;; mips*-cisco) os=-elf ;; -- cgit From ce378e7c51913c1b110e62dc35c205d8d2fad58a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 19 Jul 2009 02:32:44 +0200 Subject: Fix a few type errors in VFS modules --- source3/modules/vfs_cap.c | 10 +++++++--- source3/modules/vfs_catia.c | 3 ++- source3/modules/vfs_default.c | 5 +++-- source3/modules/vfs_dirsort.c | 3 ++- source3/modules/vfs_full_audit.c | 4 ++-- source3/modules/vfs_shadow_copy2.c | 3 ++- 6 files changed, 18 insertions(+), 10 deletions(-) diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 7e363b6be7..aa77da7cd7 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -53,7 +53,9 @@ static SMB_STRUCT_DIR *cap_opendir(vfs_handle_struct *handle, const char *fname, return SMB_VFS_NEXT_OPENDIR(handle, capname, mask, attr); } -static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp, + SMB_STRUCT_STAT *sbuf) { SMB_STRUCT_DIRENT *result; SMB_STRUCT_DIRENT *newdirent; @@ -334,7 +336,8 @@ static int cap_ntimes(vfs_handle_struct *handle, } -static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath) +static int cap_symlink(vfs_handle_struct *handle, const char *oldpath, + const char *newpath) { char *capold = capencode(talloc_tos(), oldpath); char *capnew = capencode(talloc_tos(), newpath); @@ -346,7 +349,8 @@ static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const ch return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew); } -static bool cap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz) +static int cap_readlink(vfs_handle_struct *handle, const char *path, + char *buf, size_t bufsiz) { char *cappath = capencode(talloc_tos(), path); diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index 1fd101282c..3b691c0350 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -103,7 +103,8 @@ static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle, } static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle, - SMB_STRUCT_DIR *dirp) + SMB_STRUCT_DIR *dirp, + SMB_STRUCT_STAT *sbuf) { SMB_STRUCT_DIRENT *result = NULL; SMB_STRUCT_DIRENT *newdirent = NULL; diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index c4db8fa393..bb7853b926 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1102,7 +1102,8 @@ static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle, return NT_STATUS_OK; } -static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags) +static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, + unsigned int flags) { #ifdef HAVE_CHFLAGS return chflags(path, flags); @@ -1113,7 +1114,7 @@ static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flag } static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle, - SMB_STRUCT_STAT *sbuf) + const SMB_STRUCT_STAT *sbuf) { struct file_id key; diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c index 53d1820c11..f6fc9256d0 100644 --- a/source3/modules/vfs_dirsort.c +++ b/source3/modules/vfs_dirsort.c @@ -113,7 +113,8 @@ static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle, } static SMB_STRUCT_DIRENT *dirsort_readdir(vfs_handle_struct *handle, - SMB_STRUCT_DIR *dirp) + SMB_STRUCT_DIR *dirp, + SMB_STRUCT_STAT *sbuf) { struct dirsort_privates *data = NULL; time_t current_mtime; diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index e8702aa2c8..bf53ae269c 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -561,7 +561,7 @@ static int smb_full_audit_statvfs(struct vfs_handle_struct *handle, return result; } -static int smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle) +static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle) { int result; @@ -897,7 +897,7 @@ static int smb_full_audit_lstat(vfs_handle_struct *handle, return result; } -static int smb_full_audit_get_alloc_size(vfs_handle_struct *handle, +static uint64_t smb_full_audit_get_alloc_size(vfs_handle_struct *handle, files_struct *fsp, const SMB_STRUCT_STAT *sbuf) { int result; diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 1f300a055c..29247ac7c2 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -549,7 +549,8 @@ static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname) SHADOW2_NEXT(RMDIR, (handle, name), int, -1); } -static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname, int flags) +static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname, + unsigned int flags) { SHADOW2_NEXT(CHFLAGS, (handle, name, flags), int, -1); } -- cgit From 5bf6203bc2cb63860c616556e14e2dbb07277db6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 12:10:47 +0200 Subject: Remove outdated status file about samba3 -> samba4 upgrade project. --- source4/lib/samba3/STATUS | 68 ----------------------------------------------- 1 file changed, 68 deletions(-) delete mode 100644 source4/lib/samba3/STATUS diff --git a/source4/lib/samba3/STATUS b/source4/lib/samba3/STATUS deleted file mode 100644 index e4644526df..0000000000 --- a/source4/lib/samba3/STATUS +++ /dev/null @@ -1,68 +0,0 @@ ---- Samba3 -> Samba4 Upgrade --- -(C) 2005 Jelmer Vernooij -Published under the GNU GPL - -Sponsored by the Google Summer of Code program (http://code.google.com/summerofcode.html) -Mentored by Andrew Bartlett -Thanks! - -Done: - - Reading wins.dat - - Reading registry.tdb - - Reading passdb.tdb - - Reading account_policy.tdb - - Reading group_mappings.tdb - - Reading winbindd_idmap.tdb - - Reading share_info.tdb - - Reading secrets.tdb - - Reading smbpasswd - - Reading + writing (generic) smb.conf files - - Testsuite for read support mentioned above - - Console utility for dumping Samba information - - Import user accounts in Samba4 - - Import groups in Samba4 - - Import secrets in Samba4 - - Import WINS data in Samba4 - - Dump idmap data to LDB - - Import registry keys/values in Samba4 - - Import account policies in Samba4 - - Testsuite for upgrade - - Console utility from upgrading from Samba3 -> Samba4 - - SWAT (Web interface) support for upgrading from Samba3 -> Samba4 - - LDB generic mapping module - - (Experimental) Samba4 LDB <-> Samba3 LDAP mapping module based on LDB generic mapping module - - Testsuite for Samba4 LDB <-> Samba3 LDAP mapping module - -Source files: -source/lib/ldb/modules/ldb_map.c -source/lib/ldb/modules/ldb_map.h -source/lib/samba3/group.c -source/lib/samba3/idmap.c -source/lib/samba3/policy.c -source/lib/samba3/registry.c -source/lib/samba3/samba3.c -source/lib/samba3/secrets.c -source/lib/samba3/share_info.c -source/lib/samba3/smbpasswd.c -source/lib/samba3/tdbsam.c -source/lib/samba3/winsdb.c -source/lib/samba3/samba3.h -source/scripting/libjs/upgrade.js -source/scripting/ejs/smbcalls_param.c -source/scripting/ejs/smbcalls_samba3.c -source/param/generic.c -source/param/generic.h -testdata/samba3/verify -testprogs/ejs/samba3sam -source/setup/upgrade -source/scripting/bin/samba3dump -source/dsdb/samdb/ldb_modules/samba3sam.c -source/script/tests/test_s3upgrade.sh -swat/install/samba3.esp - -Known remaining issues: - - [upgrade] Conversion from the smbpasswd/TDB passwords to ntPwdHash / lmPwdHash is broken. Couldn't find out why. - - [ldb_map] Conversion of attribute names in DN's is still a bit dodgy - - [ldb_map] mapped objectClass names may be mentioned multiple times in returned records - - [ldb_map] add/modify support not tested very well with LDAP yet (only LDB+TDB) - - [ldb_map] group membership is not yet mapped (only primaryGroupID / sambaPrimaryGroupSID) -- cgit From 04c1d02021b2e1b38d78d539655989c724f13d17 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 12:15:59 +0200 Subject: Remove unnecessary include, update README. --- source4/lib/samba3/README | 3 --- source4/lib/samba3/samba3.h | 1 - 2 files changed, 4 deletions(-) diff --git a/source4/lib/samba3/README b/source4/lib/samba3/README index 83520f673d..3f6553f7e8 100644 --- a/source4/lib/samba3/README +++ b/source4/lib/samba3/README @@ -3,6 +3,3 @@ Samba3 import, migration and compatibility. For example, the first file in this directory (smbpasswd.c) handles portions of the smbpasswd file format. - -The other files in this directory support reading the various -TDB databases from Samba3. diff --git a/source4/lib/samba3/samba3.h b/source4/lib/samba3/samba3.h index 1a0ce04143..87de13f8f8 100644 --- a/source4/lib/samba3/samba3.h +++ b/source4/lib/samba3/samba3.h @@ -22,7 +22,6 @@ #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/samr.h" -#include "param/param.h" struct samr_Password *smbpasswd_gethexpwd(TALLOC_CTX *mem_ctx, const char *p); char *smbpasswd_sethexpwd(TALLOC_CTX *mem_ctx, struct samr_Password *pwd, uint16_t acb_info); -- cgit From d8ce8f9b61cdd18d65a27623a537fbcbdf547a59 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 12:41:09 +0200 Subject: Create libndr-standard, which includes the NDR marshalling code for the "standard" set of DCE/RPC interfaces found on Windows. --- librpc/ndr_standard.pc.in | 11 +++++++++++ source4/configure.ac | 1 + source4/librpc/config.mk | 40 +++++++++++++++++++++++++--------------- source4/rpc_server/config.mk | 8 ++++---- 4 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 librpc/ndr_standard.pc.in diff --git a/librpc/ndr_standard.pc.in b/librpc/ndr_standard.pc.in new file mode 100644 index 0000000000..80eace1bef --- /dev/null +++ b/librpc/ndr_standard.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ndr-standard +Description: NDR marshallers for the standard set of DCE/RPC interfaces +Requires: ndr +Version: 0.0.1 +Libs: -L${libdir} -lndr-standard +Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1 -D_GNU_SOURCE=1 diff --git a/source4/configure.ac b/source4/configure.ac index 1930f4b6c7..7c5f310aa9 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -37,6 +37,7 @@ m4_include(client/config.m4) AC_CONFIG_FILES(lib/registry/registry.pc) AC_CONFIG_FILES(librpc/dcerpc.pc) AC_CONFIG_FILES(../librpc/ndr.pc) +AC_CONFIG_FILES(../librpc/ndr_standard.pc) AC_CONFIG_FILES(../lib/torture/torture.pc) AC_CONFIG_FILES(auth/gensec/gensec.pc) AC_CONFIG_FILES(param/samba-hostconfig.pc) diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 52c7f3e2d1..308f8cebcb 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -137,7 +137,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_FRSAPI_OBJ_FILES = ../librpc/gen_ndr/ndr_frsapi.o [SUBSYSTEM::NDR_DRSUAPI] -PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR ASN1_UTIL +PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_STANDARD ASN1_UTIL NDR_DRSUAPI_OBJ_FILES = ../librpc/gen_ndr/ndr_drsuapi.o ../librpc/ndr/ndr_drsuapi.o @@ -162,7 +162,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_UNIXINFO_OBJ_FILES = ../librpc/gen_ndr/ndr_unixinfo.o [SUBSYSTEM::NDR_SAMR] -PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA NDR_SECURITY +PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_SAMR_OBJ_FILES = ../librpc/gen_ndr/ndr_samr.o @@ -207,7 +207,7 @@ NDR_ATSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_atsvc.o PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, atsvc.h ndr_atsvc.h) [SUBSYSTEM::NDR_EVENTLOG] -PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA +PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD NDR_EVENTLOG_OBJ_FILES = ../librpc/gen_ndr/ndr_eventlog.o @@ -297,7 +297,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs.o [SUBSYSTEM::NDR_NETLOGON] -PUBLIC_DEPENDENCIES = LIBNDR NDR_SAMR NDR_LSA NDR_SECURITY +PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_NETLOGON_OBJ_FILES = ../librpc/gen_ndr/ndr_netlogon.o ../librpc/ndr/ndr_netlogon.o @@ -314,7 +314,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_KEYSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_keysvc.o [SUBSYSTEM::NDR_KRB5PAC] -PUBLIC_DEPENDENCIES = LIBNDR NDR_NETLOGON NDR_SECURITY +PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD NDR_SECURITY NDR_KRB5PAC_OBJ_FILES = ../librpc/gen_ndr/ndr_krb5pac.o ../librpc/ndr/ndr_krb5pac.o @@ -339,7 +339,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT NDR_SCHANNEL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_schannel.o [SUBSYSTEM::NDR_NBT] -PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON +PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_STANDARD LIBCLI_NDR_NETLOGON NDR_NBT_OBJ_FILES = ../librpc/gen_ndr/ndr_nbt.o @@ -356,7 +356,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT NDR_WINSREPL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winsrepl.o [SUBSYSTEM::NDR_WINBIND] -PUBLIC_DEPENDENCIES = LIBNDR NDR_NETLOGON +PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD NDR_WINBIND_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winbind.o #PUBLIC_HEADERS += $(gen_ndrsrcdir)/winbind.h @@ -374,15 +374,25 @@ $(gen_ndrsrcdir)/tables.c: $(IDL_NDR_PARSE_H_FILES) @$(PERL) ../librpc/tables.pl --output=$@ $^ > $(gen_ndrsrcdir)/tables.x @mv $(gen_ndrsrcdir)/tables.x $@ +[LIBRARY::NDR_STANDARD] +PUBLIC_DEPENDENCIES = LIBNDR +PRIVATE_DEPENDENCIES = NDR_ECHO NDR_LSA NDR_SAMR NDR_NETLOGON + +PC_FILES += $(librpcsrcdir)/ndr_standard.pc + +NDR_STANDARD_VERSION = 0.0.1 +NDR_STANDARD_SOVERSION = 0 + [SUBSYSTEM::NDR_TABLE] PUBLIC_DEPENDENCIES = \ - NDR_AUDIOSRV NDR_ECHO NDR_DCERPC \ - NDR_DSBACKUP NDR_EFS NDR_LSA NDR_DFS NDR_DRSUAPI \ - NDR_POLICYAGENT NDR_UNIXINFO NDR_SAMR NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \ + NDR_STANDARD \ + NDR_AUDIOSRV \ + NDR_DSBACKUP NDR_EFS NDR_DFS NDR_DRSUAPI \ + NDR_POLICYAGENT NDR_UNIXINFO NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \ NDR_EVENTLOG NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \ NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \ NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_NTSVCS \ - NDR_NETLOGON NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \ + NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \ NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL NDR_SECURITY \ NDR_INITSHUTDOWN NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \ NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND \ @@ -401,7 +411,7 @@ PUBLIC_DEPENDENCIES = NDR_AUDIOSRV dcerpc RPC_NDR_AUDIOSRV_OBJ_FILES = ../librpc/gen_ndr/ndr_audiosrv_c.o [SUBSYSTEM::RPC_NDR_ECHO] -PUBLIC_DEPENDENCIES = dcerpc NDR_ECHO +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD RPC_NDR_ECHO_OBJ_FILES = ../librpc/gen_ndr/ndr_echo_c.o @@ -416,7 +426,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_EFS RPC_NDR_EFS_OBJ_FILES = ../librpc/gen_ndr/ndr_efs_c.o [SUBSYSTEM::RPC_NDR_LSA] -PUBLIC_DEPENDENCIES = dcerpc NDR_LSA +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD RPC_NDR_LSA_OBJ_FILES = ../librpc/gen_ndr/ndr_lsa_c.o @@ -456,7 +466,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_IRPC RPC_NDR_IRPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_irpc_c.o [LIBRARY::dcerpc_samr] -PUBLIC_DEPENDENCIES = dcerpc NDR_SAMR +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD PC_FILES += $(librpcsrcdir)/dcerpc_samr.pc @@ -578,7 +588,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_NTSVCS RPC_NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs_c.o [SUBSYSTEM::RPC_NDR_NETLOGON] -PUBLIC_DEPENDENCIES = NDR_NETLOGON +PUBLIC_DEPENDENCIES = NDR_STANDARD RPC_NDR_NETLOGON_OBJ_FILES = ../librpc/gen_ndr/ndr_netlogon_c.o diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk index f3dc074125..4b5b5cf42f 100644 --- a/source4/rpc_server/config.mk +++ b/source4/rpc_server/config.mk @@ -19,7 +19,7 @@ PUBLIC_HEADERS += $(rpc_serversrcdir)/common/common.h [MODULE::dcerpc_rpcecho] INIT_FUNCTION = dcerpc_server_rpcecho_init SUBSYSTEM = dcerpc_server -PRIVATE_DEPENDENCIES = NDR_ECHO LIBEVENTS +PRIVATE_DEPENDENCIES = NDR_STANDARD LIBEVENTS # End MODULE dcerpc_rpcecho ################################################ @@ -99,7 +99,7 @@ SUBSYSTEM = dcerpc_server PRIVATE_DEPENDENCIES = \ SAMDB \ DCERPC_COMMON \ - NDR_SAMR + NDR_STANDARD # End MODULE dcesrv_samr ################################################ @@ -128,7 +128,7 @@ SUBSYSTEM = dcerpc_server PRIVATE_DEPENDENCIES = \ DCERPC_COMMON \ SCHANNELDB \ - NDR_NETLOGON \ + NDR_STANDARD \ auth_sam \ LIBSAMBA-HOSTCONFIG # End MODULE dcerpc_netlogon @@ -144,7 +144,7 @@ SUBSYSTEM = dcerpc_server PRIVATE_DEPENDENCIES = \ SAMDB \ DCERPC_COMMON \ - NDR_LSA \ + NDR_STANDARD \ LIBCLI_AUTH \ NDR_DSSETUP # End MODULE dcerpc_lsa -- cgit From 7a765b65b739c38ea1e3cfc136c92d2fb5ed4fa7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 13:19:54 +0200 Subject: provision: Remove unused imports. --- source4/setup/provision | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source4/setup/provision b/source4/setup/provision index 5cb851ceb7..d7fa6aa54f 100755 --- a/source4/setup/provision +++ b/source4/setup/provision @@ -22,9 +22,7 @@ # along with this program. If not, see . # -import getopt import optparse -import os import sys # Find right directory when running from source tree @@ -34,7 +32,6 @@ import samba from samba.credentials import DONT_USE_KERBEROS from samba.auth import system_session import samba.getopt as options -from samba import param from samba.provision import provision, FILL_FULL, FILL_NT4SYNC, FILL_DRS, find_setup_dir # how do we make this case insensitive?? @@ -121,7 +118,6 @@ if not opts.interactive and (opts.realm is None or opts.domain is None): if opts.interactive: from getpass import getpass - import readline import socket def ask(prompt, default=None): if default is not None: -- cgit From 28d155499a19943fca3624c814bc13e53d7c71be Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 13:39:38 +0200 Subject: Add missing includes. --- source4/libnet/libnet_samdump.c | 1 + source4/torture/auth/pac.c | 1 + 2 files changed, 2 insertions(+) diff --git a/source4/libnet/libnet_samdump.c b/source4/libnet/libnet_samdump.c index 08a2295169..8092260515 100644 --- a/source4/libnet/libnet_samdump.c +++ b/source4/libnet/libnet_samdump.c @@ -25,6 +25,7 @@ #include "../lib/util/dlinklist.h" #include "samba3/samba3.h" #include "libcli/security/security.h" +#include "param/param.h" struct samdump_secret { diff --git a/source4/torture/auth/pac.c b/source4/torture/auth/pac.c index fd54863686..076120bfee 100644 --- a/source4/torture/auth/pac.c +++ b/source4/torture/auth/pac.c @@ -29,6 +29,7 @@ #include "libcli/security/security.h" #include "torture/torture.h" #include "auth/auth_sam_reply.h" +#include "param/param.h" static bool torture_pac_self_check(struct torture_context *tctx) { -- cgit From 63a6ca084d55db95abea7abffdbe27b55f2b002f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 13:41:04 +0200 Subject: librpc: Integrate some subsystems now part of libndr-standard and integrate ndr_dfs in libndr-standard. --- source4/librpc/config.mk | 44 ++++++++++++++------------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 308f8cebcb..0d6ece5acb 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -82,7 +82,6 @@ NDR_WINSTATION_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winstation.o [SUBSYSTEM::NDR_ECHO] PUBLIC_DEPENDENCIES = LIBNDR -NDR_ECHO_OBJ_FILES = ../librpc/gen_ndr/ndr_echo.o [SUBSYSTEM::NDR_IRPC] PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_NBT @@ -114,18 +113,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC NDR_ROT_OBJ_FILES = ../librpc/gen_ndr/ndr_rot.o -[SUBSYSTEM::NDR_LSA] -PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY - -NDR_LSA_OBJ_FILES = ../librpc/gen_ndr/ndr_lsa.o - -PUBLIC_HEADERS += ../librpc/gen_ndr/lsa.h - -[SUBSYSTEM::NDR_DFS] -PUBLIC_DEPENDENCIES = LIBNDR - -NDR_DFS_OBJ_FILES = ../librpc/gen_ndr/ndr_dfs.o - [SUBSYSTEM::NDR_FRSRPC] PUBLIC_DEPENDENCIES = LIBNDR @@ -161,13 +148,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_UNIXINFO_OBJ_FILES = ../librpc/gen_ndr/ndr_unixinfo.o -[SUBSYSTEM::NDR_SAMR] -PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY - -NDR_SAMR_OBJ_FILES = ../librpc/gen_ndr/ndr_samr.o - -PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h ndr_samr_c.h) - [SUBSYSTEM::NDR_NFS4ACL] PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY @@ -296,13 +276,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs.o -[SUBSYSTEM::NDR_NETLOGON] -PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY - -NDR_NETLOGON_OBJ_FILES = ../librpc/gen_ndr/ndr_netlogon.o ../librpc/ndr/ndr_netlogon.o - -PUBLIC_HEADERS += ../librpc/gen_ndr/netlogon.h - [SUBSYSTEM::NDR_TRKWKS] PUBLIC_DEPENDENCIES = LIBNDR @@ -376,10 +349,19 @@ $(gen_ndrsrcdir)/tables.c: $(IDL_NDR_PARSE_H_FILES) [LIBRARY::NDR_STANDARD] PUBLIC_DEPENDENCIES = LIBNDR -PRIVATE_DEPENDENCIES = NDR_ECHO NDR_LSA NDR_SAMR NDR_NETLOGON +PRIVATE_DEPENDENCIES = NDR_SECURITY + +NDR_STANDARD_OBJ_FILES = ../librpc/gen_ndr/ndr_echo.o \ + ../librpc/gen_ndr/ndr_lsa.o \ + ../librpc/gen_ndr/ndr_samr.o \ + ../librpc/gen_ndr/ndr_netlogon.o \ + ../librpc/ndr/ndr_netlogon.o \ + ../librpc/gen_ndr/ndr_dfs.o PC_FILES += $(librpcsrcdir)/ndr_standard.pc +PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h lsa.h netlogon.h) + NDR_STANDARD_VERSION = 0.0.1 NDR_STANDARD_SOVERSION = 0 @@ -387,7 +369,7 @@ NDR_STANDARD_SOVERSION = 0 PUBLIC_DEPENDENCIES = \ NDR_STANDARD \ NDR_AUDIOSRV \ - NDR_DSBACKUP NDR_EFS NDR_DFS NDR_DRSUAPI \ + NDR_DSBACKUP NDR_EFS NDR_DRSUAPI \ NDR_POLICYAGENT NDR_UNIXINFO NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \ NDR_EVENTLOG NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \ NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \ @@ -431,7 +413,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD RPC_NDR_LSA_OBJ_FILES = ../librpc/gen_ndr/ndr_lsa_c.o [SUBSYSTEM::RPC_NDR_DFS] -PUBLIC_DEPENDENCIES = dcerpc NDR_DFS +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD RPC_NDR_DFS_OBJ_FILES = ../librpc/gen_ndr/ndr_dfs_c.o @@ -474,6 +456,8 @@ dcerpc_samr_VERSION = 0.0.1 dcerpc_samr_SOVERSION = 0 dcerpc_samr_OBJ_FILES = ../librpc/gen_ndr/ndr_samr_c.o +PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_samr_c.h + [SUBSYSTEM::RPC_NDR_SPOOLSS] PUBLIC_DEPENDENCIES = dcerpc NDR_SPOOLSS -- cgit From de04e00ec2bf823f90a464416e88231e97f8df59 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 15:39:52 +0200 Subject: Merge more ndr interfaces into libndr-standard. --- source4/librpc/config.mk | 78 ++++++++++++-------------------------------- source4/rpc_server/config.mk | 4 +-- 2 files changed, 23 insertions(+), 59 deletions(-) diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 0d6ece5acb..6c0b36b335 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -79,10 +79,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_WINSTATION_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winstation.o -[SUBSYSTEM::NDR_ECHO] -PUBLIC_DEPENDENCIES = LIBNDR - - [SUBSYSTEM::NDR_IRPC] PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_NBT @@ -162,35 +158,6 @@ NDR_SPOOLSS_OBJ_FILES = ../librpc/gen_ndr/ndr_spoolss.o NDR_SPOOLSS_BUF_OBJ_FILES = ../librpc/ndr/ndr_spoolss_buf.o -[SUBSYSTEM::NDR_WKSSVC] -PUBLIC_DEPENDENCIES = LIBNDR NDR_SRVSVC NDR_SECURITY - -NDR_WKSSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_wkssvc.o - -[SUBSYSTEM::NDR_SRVSVC] -PUBLIC_DEPENDENCIES = LIBNDR NDR_SVCCTL NDR_SECURITY - -NDR_SRVSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_srvsvc.o - -[SUBSYSTEM::NDR_SVCCTL] -PUBLIC_DEPENDENCIES = LIBNDR - -NDR_SVCCTL_OBJ_FILES = ../librpc/gen_ndr/ndr_svcctl.o ../librpc/ndr/ndr_svcctl.o - -PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, ndr_svcctl.h svcctl.h) - -[SUBSYSTEM::NDR_ATSVC] -PUBLIC_DEPENDENCIES = LIBNDR - -NDR_ATSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_atsvc.o - -PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, atsvc.h ndr_atsvc.h) - -[SUBSYSTEM::NDR_EVENTLOG] -PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD - -NDR_EVENTLOG_OBJ_FILES = ../librpc/gen_ndr/ndr_eventlog.o - [SUBSYSTEM::NDR_EPMAPPER] PUBLIC_DEPENDENCIES = LIBNDR @@ -216,16 +183,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins.o -[SUBSYSTEM::NDR_WINREG] -PUBLIC_DEPENDENCIES = LIBNDR NDR_INITSHUTDOWN NDR_SECURITY - -NDR_WINREG_OBJ_FILES = ../librpc/gen_ndr/ndr_winreg.o - -[SUBSYSTEM::NDR_INITSHUTDOWN] -PUBLIC_DEPENDENCIES = LIBNDR - -NDR_INITSHUTDOWN_OBJ_FILES = ../librpc/gen_ndr/ndr_initshutdown.o - [SUBSYSTEM::NDR_MGMT] PUBLIC_DEPENDENCIES = LIBNDR @@ -312,7 +269,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT NDR_SCHANNEL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_schannel.o [SUBSYSTEM::NDR_NBT] -PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_STANDARD LIBCLI_NDR_NETLOGON +PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SECURITY NDR_STANDARD LIBCLI_NDR_NETLOGON NDR_NBT_OBJ_FILES = ../librpc/gen_ndr/ndr_nbt.o @@ -356,11 +313,18 @@ NDR_STANDARD_OBJ_FILES = ../librpc/gen_ndr/ndr_echo.o \ ../librpc/gen_ndr/ndr_samr.o \ ../librpc/gen_ndr/ndr_netlogon.o \ ../librpc/ndr/ndr_netlogon.o \ - ../librpc/gen_ndr/ndr_dfs.o + ../librpc/gen_ndr/ndr_dfs.o \ + ../librpc/gen_ndr/ndr_atsvc.o \ + ../librpc/gen_ndr/ndr_wkssvc.o \ + ../librpc/gen_ndr/ndr_srvsvc.o \ + ../librpc/gen_ndr/ndr_svcctl.o \ + ../librpc/ndr/ndr_svcctl.o \ + ../librpc/gen_ndr/ndr_winreg.o \ + ../librpc/gen_ndr/ndr_initshutdown.o PC_FILES += $(librpcsrcdir)/ndr_standard.pc -PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h lsa.h netlogon.h) +PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h lsa.h netlogon.h atsvc.h ndr_atsvc.h ndr_svcctl.h svcctl.h) NDR_STANDARD_VERSION = 0.0.1 NDR_STANDARD_SOVERSION = 0 @@ -370,13 +334,13 @@ PUBLIC_DEPENDENCIES = \ NDR_STANDARD \ NDR_AUDIOSRV \ NDR_DSBACKUP NDR_EFS NDR_DRSUAPI \ - NDR_POLICYAGENT NDR_UNIXINFO NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \ - NDR_EVENTLOG NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \ - NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \ + NDR_POLICYAGENT NDR_UNIXINFO NDR_SPOOLSS \ + NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \ + NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \ NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_NTSVCS \ NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \ - NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL NDR_SECURITY \ - NDR_INITSHUTDOWN NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \ + NDR_ROT NDR_DRSBLOBS NDR_NBT NDR_WINSREPL NDR_SECURITY \ + NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \ NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND \ NDR_DCOM NDR_WMI NDR_NAMED_PIPE_AUTH @@ -464,7 +428,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_SPOOLSS RPC_NDR_SPOOLSS_OBJ_FILES = ../librpc/gen_ndr/ndr_spoolss_c.o [SUBSYSTEM::RPC_NDR_WKSSVC] -PUBLIC_DEPENDENCIES = dcerpc NDR_WKSSVC +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD RPC_NDR_WKSSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_wkssvc_c.o @@ -474,14 +438,14 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_SRVSVC RPC_NDR_SRVSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_srvsvc_c.o [SUBSYSTEM::RPC_NDR_SVCCTL] -PUBLIC_DEPENDENCIES = dcerpc NDR_SVCCTL +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD RPC_NDR_SVCCTL_OBJ_FILES = ../librpc/gen_ndr/ndr_svcctl_c.o PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_svcctl_c.h [LIBRARY::dcerpc_atsvc] -PUBLIC_DEPENDENCIES = dcerpc NDR_ATSVC +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD dcerpc_atsvc_VERSION = 0.0.1 dcerpc_atsvc_SOVERSION = 0 @@ -492,7 +456,7 @@ PC_FILES += $(librpcsrcdir)/dcerpc_atsvc.pc PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_atsvc_c.h [SUBSYSTEM::RPC_NDR_EVENTLOG] -PUBLIC_DEPENDENCIES = dcerpc NDR_EVENTLOG +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD RPC_NDR_EVENTLOG_OBJ_FILES = ../librpc/gen_ndr/ndr_eventlog_c.o @@ -522,12 +486,12 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_WINS RPC_NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins_c.o [SUBSYSTEM::RPC_NDR_WINREG] -PUBLIC_DEPENDENCIES = dcerpc NDR_WINREG +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD RPC_NDR_WINREG_OBJ_FILES = ../librpc/gen_ndr/ndr_winreg_c.o [SUBSYSTEM::RPC_NDR_INITSHUTDOWN] -PUBLIC_DEPENDENCIES = dcerpc NDR_INITSHUTDOWN +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD RPC_NDR_INITSHUTDOWN_OBJ_FILES = ../librpc/gen_ndr/ndr_initshutdown_c.o diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk index 4b5b5cf42f..32669db37a 100644 --- a/source4/rpc_server/config.mk +++ b/source4/rpc_server/config.mk @@ -69,7 +69,7 @@ $(eval $(call proto_header_template,$(rpc_serversrcdir)/srvsvc/proto.h,$(dcerpc_ INIT_FUNCTION = dcerpc_server_wkssvc_init SUBSYSTEM = dcerpc_server PRIVATE_DEPENDENCIES = \ - DCERPC_COMMON NDR_WKSSVC + DCERPC_COMMON NDR_STANDARD # End MODULE dcerpc_wkssvc ################################################ @@ -114,7 +114,7 @@ INIT_FUNCTION = dcerpc_server_winreg_init SUBSYSTEM = dcerpc_server OUTPUT_TYPE = MERGED_OBJ PRIVATE_DEPENDENCIES = \ - registry NDR_WINREG + registry NDR_STANDARD # End MODULE dcerpc_winreg ################################################ -- cgit From 5b4cb31ef1359d8c39dbffc028abb68652cc2186 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Thu, 9 Jul 2009 17:54:42 +0200 Subject: Cosmetic correction Changes the order of two commands. First set up the "priv" structure, then assign it to the "ntvfs" structure. --- source4/ntvfs/unixuid/vfs_unixuid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 3ef341d61a..97c306f7c3 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -310,9 +310,9 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_ERROR; } - ntvfs->private_data = priv; priv->last_sec_ctx = NULL; priv->last_token = NULL; + ntvfs->private_data = priv; tevent_loop_set_nesting_hook(ntvfs->ctx->event_ctx, unixuid_event_nesting_hook, -- cgit From dbedfc318e2984238ee0acdb19a1a70fda8f4381 Mon Sep 17 00:00:00 2001 From: Matt Kraai Date: Thu, 9 Jul 2009 09:45:28 -0700 Subject: include unix.h if it's available --- lib/replace/libreplace.m4 | 1 + lib/replace/replace.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/lib/replace/libreplace.m4 b/lib/replace/libreplace.m4 index 2d90d9c7e8..a3a26ef43e 100644 --- a/lib/replace/libreplace.m4 +++ b/lib/replace/libreplace.m4 @@ -103,6 +103,7 @@ AC_CHECK_HEADERS(sys/time.h time.h) AC_CHECK_HEADERS(stdarg.h vararg.h) AC_CHECK_HEADERS(sys/mount.h mntent.h) AC_CHECK_HEADERS(stropts.h) +AC_CHECK_HEADERS(unix.h) AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror) AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename) diff --git a/lib/replace/replace.h b/lib/replace/replace.h index fe1f732acb..2db6aa1226 100644 --- a/lib/replace/replace.h +++ b/lib/replace/replace.h @@ -258,6 +258,10 @@ char *rep_realpath(const char *path, char *resolved_path); int rep_lchown(const char *fname,uid_t uid,gid_t gid); #endif +#ifdef HAVE_UNIX_H +#include +#endif + #ifndef HAVE_SETLINEBUF #define setlinebuf rep_setlinebuf void rep_setlinebuf(FILE *); -- cgit From cb53b780803bc9a6dc02b16a64abe408727f69b4 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Fri, 17 Jul 2009 18:13:28 +0200 Subject: [SAMBA 4] Some cosmetic changes for the LDB modules Some corrections which make the code a bit more readable (no functional changes here) --- source4/dsdb/samdb/ldb_modules/linked_attributes.c | 11 +++++------ source4/dsdb/samdb/ldb_modules/password_hash.c | 13 +++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c index 4e28c8a149..9ed06a9130 100644 --- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c +++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c @@ -741,15 +741,15 @@ static int la_op_search_callback(struct ldb_request *req, if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } - break; - case LDB_RENAME: - + return ret; + + case LDB_RENAME: + /* start the mod requests chain */ ret = la_do_mod_request(ac); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); - } - + } return ret; default: @@ -759,7 +759,6 @@ static int la_op_search_callback(struct ldb_request *req, return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } - return LDB_SUCCESS; } talloc_free(ares); diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index ef641ac18b..c7fa636aa8 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -1400,33 +1400,33 @@ static int setup_password_fields(struct setup_password_fields_io *io) } ret = setup_kerberos_keys(io); - if (ret != 0) { + if (ret != LDB_SUCCESS) { return ret; } } ret = setup_nt_fields(io); - if (ret != 0) { + if (ret != LDB_SUCCESS) { return ret; } ret = setup_lm_fields(io); - if (ret != 0) { + if (ret != LDB_SUCCESS) { return ret; } ret = setup_supplemental_field(io); - if (ret != 0) { + if (ret != LDB_SUCCESS) { return ret; } ret = setup_last_set_field(io); - if (ret != 0) { + if (ret != LDB_SUCCESS) { return ret; } ret = setup_kvno_field(io); - if (ret != 0) { + if (ret != LDB_SUCCESS) { return ret; } @@ -1649,6 +1649,7 @@ static int get_domain_data_callback(struct ldb_request *req, if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } + break; case LDB_REPLY_REFERRAL: /* ignore */ -- cgit From 295c3724a30013c572d3a3fdd3a8acc6ed19c546 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Wed, 15 Jul 2009 13:25:04 +0200 Subject: Fix typo --- source4/libcli/security/security_token.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c index e1349e06f8..0764dfeb8f 100644 --- a/source4/libcli/security/security_token.c +++ b/source4/libcli/security/security_token.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. - security descriptror utility functions + security descriptor utility functions Copyright (C) Andrew Tridgell 2004 Copyright (C) Stefan Metzmacher 2005 -- cgit From a817cff5a0f17c6a8b35013483a18c70acdfaa1c Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Sat, 11 Jul 2009 15:57:35 +0200 Subject: Fix broken password quality check This fixes broken password tests when the passwords contain non ASCII characters (e.g. accentuated chars like ('e, `e, ...) --- lib/util/genrand.c | 3 ++- lib/util/tests/genrand.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/util/genrand.c b/lib/util/genrand.c index cd1823a9a0..c51f9384b8 100644 --- a/lib/util/genrand.c +++ b/lib/util/genrand.c @@ -294,6 +294,7 @@ _PUBLIC_ uint32_t generate_random(void) _PUBLIC_ bool check_password_quality(const char *s) { int has_digit=0, has_capital=0, has_lower=0, has_special=0, has_high=0; + char* reals = s; while (*s) { if (isdigit((unsigned char)*s)) { has_digit |= 1; @@ -310,7 +311,7 @@ _PUBLIC_ bool check_password_quality(const char *s) } return ((has_digit + has_lower + has_capital + has_special) >= 3 - || (has_high > strlen(s)/2)); + || (has_high > strlen(reals)/2)); } /** diff --git a/lib/util/tests/genrand.c b/lib/util/tests/genrand.c index 5fe229c089..20a20ac7fa 100644 --- a/lib/util/tests/genrand.c +++ b/lib/util/tests/genrand.c @@ -40,6 +40,8 @@ static bool test_check_password_quality(struct torture_context *tctx) torture_assert(tctx, !check_password_quality("aaaaaaaaaaaa"), "same char password"); torture_assert(tctx, !check_password_quality("BLA"), "multiple upcases password"); torture_assert(tctx, !check_password_quality("123"), "digits only"); + torture_assert(tctx, !check_password_quality("matthiéu"), "not enough high symbols"); + torture_assert(tctx, check_password_quality("abcdééàçè"), "valid"); torture_assert(tctx, check_password_quality("A2e"), "valid"); torture_assert(tctx, check_password_quality("BA2eLi443"), "valid"); return true; -- cgit From 5f8df164716a43bd9e6c22dfd1f066bf96ccf273 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Sat, 18 Jul 2009 16:28:53 +0700 Subject: lib/util/util_file.c(file_save): fixed file descriptor leak when read(2) fails. Found by cppcheck: [./lib/util/util_file.c:383]: (error) Resource leak: fd --- lib/util/util_file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/util/util_file.c b/lib/util/util_file.c index 0275e78c54..7466004e5c 100644 --- a/lib/util/util_file.c +++ b/lib/util/util_file.c @@ -380,6 +380,7 @@ _PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length) return false; } if (write(fd, packet, length) != (size_t)length) { + close(fd); return false; } close(fd); -- cgit From 11fa3ed9ee1a05aabdba902db9899dfeb664b324 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Sat, 18 Jul 2009 23:30:33 +0700 Subject: source4/lib/registry/patchfile.c(reg_diff_load): fixed possible resource leak. File descriptor leaks when write(2) fails and we are returning from function. Found by cppcheck: [./source4/lib/registry/patchfile.c:319]: (error) Resource leak: fd --- source4/lib/registry/patchfile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 925806985e..24d86abf48 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -316,6 +316,7 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename, if (read(fd, &hdr, 4) != 4) { DEBUG(0, ("Error reading registry patch file `%s'\n", filename)); + close(fd); return WERR_GENERAL_FAILURE; } -- cgit From de2a9fb60704eda5ba22e5d3b14111628acef2e8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 17:17:23 +0200 Subject: Remove unused variable. --- source4/torture/rpc/object_uuid.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source4/torture/rpc/object_uuid.c b/source4/torture/rpc/object_uuid.c index a70266697e..53d03a3ce9 100644 --- a/source4/torture/rpc/object_uuid.c +++ b/source4/torture/rpc/object_uuid.c @@ -35,7 +35,6 @@ static bool test_random_uuid(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2; - struct rpc_request *req; struct GUID uuid; struct dssetup_DsRoleGetPrimaryDomainInformation r1; struct lsa_GetUserName r2; -- cgit From 4447bd96b90ce4bfca793d482f9dcbd98e6579a5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 17:18:04 +0200 Subject: Include ntsvc NDR in libndr-standard. --- source4/librpc/config.mk | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 6c0b36b335..9e3d6b27ea 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -228,11 +228,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_scerpc.o -[SUBSYSTEM::NDR_NTSVCS] -PUBLIC_DEPENDENCIES = LIBNDR - -NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs.o - [SUBSYSTEM::NDR_TRKWKS] PUBLIC_DEPENDENCIES = LIBNDR @@ -320,7 +315,9 @@ NDR_STANDARD_OBJ_FILES = ../librpc/gen_ndr/ndr_echo.o \ ../librpc/gen_ndr/ndr_svcctl.o \ ../librpc/ndr/ndr_svcctl.o \ ../librpc/gen_ndr/ndr_winreg.o \ - ../librpc/gen_ndr/ndr_initshutdown.o + ../librpc/gen_ndr/ndr_initshutdown.o \ + ../librpc/gen_ndr/ndr_eventlog.o \ + ../librpc/gen_ndr/ndr_ntsvcs.o PC_FILES += $(librpcsrcdir)/ndr_standard.pc @@ -337,7 +334,7 @@ PUBLIC_DEPENDENCIES = \ NDR_POLICYAGENT NDR_UNIXINFO NDR_SPOOLSS \ NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \ NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \ - NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_NTSVCS \ + NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC \ NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \ NDR_ROT NDR_DRSBLOBS NDR_NBT NDR_WINSREPL NDR_SECURITY \ NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \ @@ -531,7 +528,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_SCERPC RPC_NDR_SCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_scerpc_c.o [SUBSYSTEM::RPC_NDR_NTSVCS] -PUBLIC_DEPENDENCIES = dcerpc NDR_NTSVCS +PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD RPC_NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs_c.o -- cgit From 478446f96dae1f42312b72fda4210f1300023e57 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 18:51:15 +0200 Subject: Remove unnecessary imports. --- source4/scripting/python/samba/__init__.py | 1 - source4/scripting/python/samba/getopt.py | 2 +- source4/scripting/python/samba/idmap.py | 2 -- source4/scripting/python/samba/provision.py | 5 ++--- source4/scripting/python/samba/samba3.py | 4 ++-- source4/scripting/python/samba/upgrade.py | 9 ++++----- 6 files changed, 9 insertions(+), 14 deletions(-) diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 131d1a3ac6..164803bb65 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -42,7 +42,6 @@ else: import ldb -import credentials import glue class Ldb(ldb.Ldb): diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index c12245f6c5..8b756b2d6f 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -20,7 +20,7 @@ """Support for parsing Samba-related command-line options.""" import optparse -from credentials import Credentials, AUTO_USE_KERBEROS, DONT_USE_KERBEROS, MUST_USE_KERBEROS +from credentials import Credentials, DONT_USE_KERBEROS, MUST_USE_KERBEROS from hostconfig import Hostconfig __docformat__ = "restructuredText" diff --git a/source4/scripting/python/samba/idmap.py b/source4/scripting/python/samba/idmap.py index f8eeb18925..ee79be1af9 100644 --- a/source4/scripting/python/samba/idmap.py +++ b/source4/scripting/python/samba/idmap.py @@ -23,8 +23,6 @@ __docformat__ = "restructuredText" import samba -import glue -import ldb class IDmapDB(samba.Ldb): """The IDmap database.""" diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 8f57105224..8a7ed6a86e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -38,13 +38,12 @@ import registry import samba from auth import system_session from samba import version, Ldb, substitute_var, valid_netbios_name, check_all_substituted, \ - DS_BEHAVIOR_WIN2000, DS_BEHAVIOR_WIN2003_INTERIM, DS_BEHAVIOR_WIN2003, DS_BEHAVIOR_WIN2008 + DS_BEHAVIOR_WIN2008 from samba.samdb import SamDB from samba.idmap import IDmapDB from samba.dcerpc import security import urllib -from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ - timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE +from ldb import SCOPE_SUBTREE, LdbError, timestring from ms_schema import read_ms_schema __docformat__ = "restructuredText" diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index c8ddbc8864..179efa2700 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -502,7 +502,7 @@ TDBSAM_USER_PREFIX = "USER_" class LdapSam(object): """Samba 3 LDAP passdb backend reader.""" def __init__(self, url): - self.ldap_url = ldap_url + self.ldap_url = url class TdbSam(TdbDatabase): @@ -692,7 +692,7 @@ class ParamFile(object): (k, v) = l.split("=", 1) self._sections[section][self._sanitize_name(k)] = v else: - raise Error("Unable to parser line %d: %r" % (i+1,l)) + raise Exception("Unable to parser line %d: %r" % (i+1,l)) def get(self, param, section=None): """Return the value of a parameter. diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 0c83604e82..81945525e6 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -9,17 +9,16 @@ __docformat__ = "restructuredText" -from provision import findnss, provision, FILL_DRS +from provision import provision, FILL_DRS import grp import ldb import time import pwd -import uuid import registry from samba import Ldb -from samba.samdb import SamDB +from samba.param import LoadParm -def import_sam_policy(samldb, samba3_policy, domaindn): +def import_sam_policy(samldb, policy, dn): """Import a Samba 3 policy database.""" samldb.modify_ldif(""" dn: %s @@ -394,7 +393,7 @@ def upgrade_smbconf(oldconf,mark): kept in the new configuration as "samba3:" """ data = oldconf.data() - newconf = param_init() + newconf = LoadParm() for s in data: for p in data[s]: -- cgit From 54670bb400f2f8c05d8331dbf17831354600e186 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 18:58:22 +0200 Subject: Remove unused parameter setting. --- lib/torture/torture.c | 8 -------- lib/torture/torture.h | 3 --- 2 files changed, 11 deletions(-) diff --git a/lib/torture/torture.c b/lib/torture/torture.c index 99447e7e53..392cb0ad4c 100644 --- a/lib/torture/torture.c +++ b/lib/torture/torture.c @@ -65,7 +65,6 @@ struct torture_context *torture_context_child(struct torture_context *parent) if (subtorture == NULL) return NULL; - subtorture->level = parent->level+1; subtorture->ev = talloc_reference(subtorture, parent->ev); subtorture->lp_ctx = talloc_reference(subtorture, parent->lp_ctx); subtorture->outputdir = talloc_reference(subtorture, parent->outputdir); @@ -257,7 +256,6 @@ bool torture_run_suite(struct torture_context *context, struct torture_suite *tsuite; char *old_testname; - context->level++; if (context->results->ui_ops->suite_start) context->results->ui_ops->suite_start(context, suite); @@ -282,8 +280,6 @@ bool torture_run_suite(struct torture_context *context, if (context->results->ui_ops->suite_finish) context->results->ui_ops->suite_finish(context, suite); - context->level--; - return ret; } @@ -378,8 +374,6 @@ bool torture_run_tcase(struct torture_context *context, char *old_testname; struct torture_test *test; - context->level++; - context->active_tcase = tcase; if (context->results->ui_ops->tcase_start) context->results->ui_ops->tcase_start(context, tcase); @@ -415,8 +409,6 @@ done: if (context->results->ui_ops->tcase_finish) context->results->ui_ops->tcase_finish(context, tcase); - context->level--; - return ret; } diff --git a/lib/torture/torture.h b/lib/torture/torture.h index bc6365351e..e28801e269 100644 --- a/lib/torture/torture.h +++ b/lib/torture/torture.h @@ -86,9 +86,6 @@ struct torture_context /** Directory used for temporary test data */ const char *outputdir; - /** Indentation level */ - int level; - /** Event context */ struct tevent_context *ev; -- cgit From 54a2f51d57a24104f1facff2674b4d441cdfde48 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 20:42:52 +0200 Subject: pidl: Print proper errors when arrays don't have a specified size rather than spewing pages of perl warnings. --- pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm | 14 ++++++++++---- pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm | 11 ++++++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm index ed1b71a236..a2a61d87d0 100644 --- a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm +++ b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm @@ -96,11 +96,17 @@ sub ParseOutputArgument($$$) # structure, the user should be able to know the size beforehand # to allocate a structure of the right size. my $env = GenerateFunctionInEnv($fn, "r."); - my $size_is = ParseExpr($e->{LEVELS}[$level]->{SIZE_IS}, $env, $e->{ORIGINAL}); - if (has_property($e, "charset")) { - $self->pidl("memcpy(CONST_DISCARD(char *, $e->{NAME}), r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));"); + my $l = $e->{LEVELS}[$level]; + unless (defined($l->{SIZE_IS})) { + error($e->{ORIGINAL}, "no size known for [out] array `$e->{NAME}'"); + $self->pidl('#error No size known for [out] array `$e->{NAME}'); } else { - $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));"); + my $size_is = ParseExpr($l->{SIZE_IS}, $env, $e->{ORIGINAL}); + if (has_property($e, "charset")) { + $self->pidl("memcpy(CONST_DISCARD(char *, $e->{NAME}), r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));"); + } else { + $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));"); + } } } else { $self->pidl("*$e->{NAME} = *r.out.$e->{NAME};"); diff --git a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm index c9a8eea59f..5599de9d79 100644 --- a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm +++ b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm @@ -11,7 +11,7 @@ use Exporter; @EXPORT_OK = qw(DeclLevel); use strict; -use Parse::Pidl qw(warning fatal); +use Parse::Pidl qw(warning error fatal); use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference); use Parse::Pidl::Util qw(ParseExpr has_property is_constant); use Parse::Pidl::NDR qw(GetNextLevel); @@ -72,8 +72,13 @@ sub AllocOutVar($$$$$) } if ($l->{TYPE} eq "ARRAY") { - my $size = ParseExpr($l->{SIZE_IS}, $env, $e); - pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);"; + unless(defined($l->{SIZE_IS})) { + error($e->{ORIGINAL}, "No size known for array `$e->{NAME}'"); + pidl "#error No size known for array `$e->{NAME}'"; + } else { + my $size = ParseExpr($l->{SIZE_IS}, $env, $e); + pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);"; + } } else { pidl "$name = talloc_zero($mem_ctx, " . DeclLevel($e, 1) . ");"; } -- cgit From 7889823783625e16e273770f73f285920828e411 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Jul 2009 21:12:56 +0200 Subject: pidl: Print actual type names in errors about unknown origins rather than 'HASH(0x....)'. --- pidl/lib/Parse/Pidl/Samba4/Python.pm | 30 +++++++++++++++--------------- pidl/lib/Parse/Pidl/Typelist.pm | 7 +++++-- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index 81869b0da5..d27192d6dd 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -431,7 +431,7 @@ sub PythonFunctionUnpackOut($$$) } elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "WERROR") { $self->handle_werror("r->out.result", "NULL", undef); } elsif (defined($fn->{RETURN_TYPE})) { - my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result"); + my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result", $fn); if ($result_size > 1) { $self->pidl("PyTuple_SetItem(result, $i, $conv);"); } else { @@ -815,11 +815,11 @@ sub assign($$$) } } -sub ConvertObjectFromPythonData($$$$$$) +sub ConvertObjectFromPythonData($$$$$$;$) { - my ($self, $mem_ctx, $cvar, $ctype, $target, $fail) = @_; + my ($self, $mem_ctx, $cvar, $ctype, $target, $fail, $location) = @_; - die("undef type for $cvar") unless(defined($ctype)); + fatal($location, "undef type for $cvar") unless(defined($ctype)); $ctype = resolveType($ctype); @@ -839,7 +839,7 @@ sub ConvertObjectFromPythonData($$$$$$) if ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") { my $ctype_name = $self->use_type_variable($ctype); unless (defined ($ctype_name)) { - error(undef, "Unable to determine origin of type " . mapTypeName($ctype)); + error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'"); $self->assign($target, "NULL"); # FIXME: return; @@ -886,7 +886,7 @@ sub ConvertObjectFromPythonData($$$$$$) return; } - fatal($ctype, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar"); + fatal($location, "unknown type `$actual_ctype->{TYPE}' for ".mapTypeName($ctype) . ": $cvar"); } @@ -946,7 +946,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) { $var_name = get_pointer_to($var_name); } - $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail); + $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail, $e->{ORIGINAL}); } elsif ($l->{TYPE} eq "SWITCH") { $var_name = get_pointer_to($var_name); my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e); @@ -954,7 +954,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) } elsif ($l->{TYPE} eq "SUBCONTEXT") { $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail); } else { - die("unknown level type $l->{TYPE}"); + fatal($e->{ORIGINAL}, "unknown level type $l->{TYPE}"); } } @@ -1003,9 +1003,9 @@ sub ConvertScalarToPython($$$) die("Unknown scalar type $ctypename"); } -sub ConvertObjectToPythonData($$$$$) +sub ConvertObjectToPythonData($$$$$;$) { - my ($self, $mem_ctx, $ctype, $cvar) = @_; + my ($self, $mem_ctx, $ctype, $cvar, $location) = @_; die("undef type for $cvar") unless(defined($ctype)); @@ -1027,13 +1027,13 @@ sub ConvertObjectToPythonData($$$$$) } elsif ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") { my $ctype_name = $self->use_type_variable($ctype); unless (defined($ctype_name)) { - error(undef, "Unable to determine origin of type " . mapTypeName($ctype)); + error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'"); return "NULL"; # FIXME! } return "py_talloc_import_ex($ctype_name, $mem_ctx, $cvar)"; } - fatal($ctype, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar"); + fatal($location, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar"); } sub fail_on_null($$$) @@ -1113,12 +1113,12 @@ sub ConvertObjectToPythonLevel($$$$$$) if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) { $var_name = get_pointer_to($var_name); } - my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name); + my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $e->{ORIGINAL}); $self->pidl("$py_var = $conv;"); } elsif ($l->{TYPE} eq "SUBCONTEXT") { $self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, GetNextLevel($e, $l), $var_name, $py_var, $fail); } else { - die("Unknown level type $l->{TYPE} $var_name"); + fatal($e->{ORIGINAL}, "Unknown level type $l->{TYPE} $var_name"); } } @@ -1223,7 +1223,7 @@ sub Parse($$$$$) } elsif ($cvar =~ /^".*"$/) { $py_obj = "PyString_FromString($cvar)"; } else { - $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar); + $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar, undef); } $self->pidl("PyModule_AddObject(m, \"$name\", $py_obj);"); diff --git a/pidl/lib/Parse/Pidl/Typelist.pm b/pidl/lib/Parse/Pidl/Typelist.pm index e63b3c990f..12ffa92bf6 100644 --- a/pidl/lib/Parse/Pidl/Typelist.pm +++ b/pidl/lib/Parse/Pidl/Typelist.pm @@ -273,12 +273,15 @@ sub mapTypeName($) my $dt; $t = expandAlias($t); - unless ($dt or ($dt = getType($t))) { + if ($dt = getType($t)) { + return mapType($dt, $dt->{NAME}); + } elsif (ref($t) eq "HASH" and defined($t->{NAME})) { + return mapType($t, $t->{NAME}); + } else { # Best guess return "struct $t"; } - return mapType($dt, $dt->{NAME}); } sub LoadIdl($;$) -- cgit From 2fc5331e5c23e3f448b53fa7838e478772d0caed Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Fri, 10 Jul 2009 12:48:18 +0200 Subject: [SAMBA 4 directory] Refactoring and clean up of directory structure - Adds more system objects which make sense to have them in SAMBA 4 also to have them when we add more and more services related to the directory (volume support, DFS, replication service, COM...) - Make sure that "isCriticalSystemObject" and "showInAdvancedViewOnly" attributes are set correctly on each object --- source4/setup/provision.ldif | 184 ++++++++++++++++++++------ source4/setup/provision_basedn_modify.ldif | 6 +- source4/setup/provision_computers_modify.ldif | 6 +- source4/setup/provision_configuration.ldif | 1 + source4/setup/provision_group_policy.ldif | 11 -- source4/setup/provision_self_join.ldif | 5 +- source4/setup/provision_users.ldif | 26 ++-- source4/setup/provision_users_modify.ldif | 6 +- source4/setup/schema_samba4.ldif | 3 - 9 files changed, 167 insertions(+), 81 deletions(-) diff --git a/source4/setup/provision.ldif b/source4/setup/provision.ldif index e5b20d03e1..9f50b45dff 100644 --- a/source4/setup/provision.ldif +++ b/source4/setup/provision.ldif @@ -1,7 +1,28 @@ +dn: CN=Builtin,${DOMAINDN} +objectClass: top +objectClass: builtinDomain +forceLogoff: -9223372036854775808 +lockoutDuration: -18000000000 +lockOutObservationWindow: -18000000000 +lockoutThreshold: 0 +maxPwdAge: -37108517437440 +minPwdAge: 0 +minPwdLength: 0 +modifiedCountAtLastProm: 0 +nextRid: 1000 +pwdProperties: 0 +pwdHistoryLength: 0 +objectSid: S-1-5-32 +serverState: 1 +uASCompat: 1 +modifiedCount: 1 +systemFlags: -1946157056 +isCriticalSystemObject: TRUE +showInAdvancedViewOnly: FALSE + dn: OU=Domain Controllers,${DOMAINDN} objectClass: top objectClass: organizationalUnit -cn: Domain Controllers description: Default container for domain controllers systemFlags: -1946157056 isCriticalSystemObject: TRUE @@ -10,82 +31,171 @@ showInAdvancedViewOnly: FALSE dn: CN=ForeignSecurityPrincipals,${DOMAINDN} objectClass: top objectClass: container -cn: ForeignSecurityPrincipals description: Default container for security identifiers (SIDs) associated with objects from external, trusted domains systemFlags: -1946157056 isCriticalSystemObject: TRUE showInAdvancedViewOnly: FALSE +dn: CN=Infrastructure,${DOMAINDN} +objectClass: top +objectClass: infrastructureUpdate +systemFlags: -1946157056 +fSMORoleOwner: CN=NTDS Settings,${SERVERDN} +isCriticalSystemObject: TRUE + +dn: CN=LostAndFound,${DOMAINDN} +objectClass: top +objectClass: lostAndFound +description: Default container for orphaned objects +systemFlags: -1946157056 +isCriticalSystemObject: TRUE + +dn: CN=NTDS Quotas,${DOMAINDN} +objectClass: top +objectClass: msDS-QuotaContainer +description: Quota specifications container +msDS-TombstoneQuotaFactor: 100 +systemFlags: -1946157056 +isCriticalSystemObject: TRUE + +dn: CN=Program Data,${DOMAINDN} +objectClass: top +objectClass: container +description: Default location for storage of application data. + +dn: CN=Microsoft,CN=Program Data,${DOMAINDN} +objectClass: top +objectClass: container +description: Default location for storage of Microsoft application data. + dn: CN=System,${DOMAINDN} objectClass: top objectClass: container -cn: System description: Builtin system settings systemFlags: -1946157056 isCriticalSystemObject: TRUE -dn: CN=RID Manager$,CN=System,${DOMAINDN} -objectclass: top -objectclass: rIDManager -cn: RID Manager$ +dn: CN=AdminSDHolder,CN=System,${DOMAINDN} +objectClass: top +objectClass: container systemFlags: -1946157056 isCriticalSystemObject: TRUE -fSMORoleOwner: CN=NTDS Settings,${SERVERDN} -rIDAvailablePool: 4611686014132423217 + +dn: CN=ComPartitions,CN=System,${DOMAINDN} +objectClass: top +objectClass: container +systemFlags: -1946157056 +isCriticalSystemObject: TRUE + +dn: CN=ComPartitionSets,CN=System,${DOMAINDN} +objectClass: top +objectClass: container +systemFlags: -1946157056 +isCriticalSystemObject: TRUE + +dn: CN=Default Domain Policy,CN=System,${DOMAINDN} +objectClass: top +objectClass: leaf +objectClass: domainPolicy +isCriticalSystemObject: TRUE + +dn: CN=AppCategories,CN=Default Domain Policy,CN=System,${DOMAINDN} +objectClass: top +objectClass: classStore +isCriticalSystemObject: TRUE + +dn: CN=Dfs-Configuration,CN=System,${DOMAINDN} +objectClass: top +objectClass: dfsConfiguration +isCriticalSystemObject: TRUE +showInAdvancedViewOnly: FALSE dn: CN=DomainUpdates,CN=System,${DOMAINDN} objectClass: top objectClass: container -cn: DomainUpdates + +dn: CN=Operations,CN=DomainUpdates,CN=System,${DOMAINDN} +objectClass: top +objectClass: container dn: CN=Windows2003Update,CN=DomainUpdates,CN=System,${DOMAINDN} objectClass: top objectClass: container -cn: Windows2003Update revision: 8 -dn: CN=Infrastructure,${DOMAINDN} -objectclass: top -objectclass: infrastructureUpdate -cn: Infrastructure +dn: CN=File Replication Service,CN=System,${DOMAINDN} +objectClass: top +objectClass: applicationSettings +objectClass: nTFRSSettings systemFlags: -1946157056 isCriticalSystemObject: TRUE -fSMORoleOwner: CN=NTDS Settings,${SERVERDN} -dn: CN=Builtin,${DOMAINDN} +dn: CN=FileLinks,CN=System,${DOMAINDN} objectClass: top -objectClass: builtinDomain -cn: Builtin -forceLogoff: -9223372036854775808 -lockoutDuration: -18000000000 -lockOutObservationWindow: -18000000000 -lockoutThreshold: 0 -maxPwdAge: -37108517437440 -minPwdAge: 0 -minPwdLength: 0 -modifiedCountAtLastProm: 0 -nextRid: 1000 -pwdProperties: 0 -pwdHistoryLength: 0 -objectSid: S-1-5-32 -serverState: 1 -uASCompat: 1 -modifiedCount: 1 +objectClass: fileLinkTracking +systemFlags: -1946157056 isCriticalSystemObject: TRUE -showInAdvancedViewOnly: FALSE + +dn: CN=ObjectMoveTable,CN=FileLinks,CN=System,${DOMAINDN} +objectClass: top +objectClass: fileLinkTracking +objectClass: linkTrackObjectMoveTable +systemFlags: -1946157056 +isCriticalSystemObject: TRUE + +dn: CN=VolumeTable,CN=FileLinks,CN=System,${DOMAINDN} +objectClass: top +objectClass: fileLinkTracking +objectClass: linkTrackVolumeTable systemFlags: -1946157056 +isCriticalSystemObject: TRUE + +dn: CN=IP Security,CN=System,${DOMAINDN} +objectClass: top +objectClass: container +isCriticalSystemObject: TRUE + +dn: CN=Meetings,CN=System,${DOMAINDN} +objectClass: top +objectClass: container +isCriticalSystemObject: TRUE dn: CN=Policies,CN=System,${DOMAINDN} objectClass: top objectClass: container systemFlags: -1946157056 +isCriticalSystemObject: TRUE -dn: CN=IP Security,CN=System,${DOMAINDN} +dn: CN=RAS and IAS Servers Access Check,CN=System,${DOMAINDN} objectClass: top objectClass: container +systemFlags: -1946157056 +isCriticalSystemObject: TRUE -dn: CN=ComPartitionSets,CN=System,${DOMAINDN} +dn: CN=RID Manager$,CN=System,${DOMAINDN} +objectClass: top +objectClass: rIDManager +systemFlags: -1946157056 +fSMORoleOwner: CN=NTDS Settings,${SERVERDN} +rIDAvailablePool: 4611686014132423217 +isCriticalSystemObject: TRUE + +dn: CN=RpcServices,CN=System,${DOMAINDN} objectClass: top objectClass: container +objectClass: rpcContainer systemFlags: -1946157056 +isCriticalSystemObject: TRUE + +dn: CN=Server,CN=System,${DOMAINDN} +objectClass: top +objectClass: securityObject +objectClass: samServer +systemFlags: -1946157056 +revision: 65543 +isCriticalSystemObject: TRUE +dn: CN=WinsockServices,CN=System,${DOMAINDN} +objectClass: top +objectClass: container +isCriticalSystemObject: TRUE diff --git a/source4/setup/provision_basedn_modify.ldif b/source4/setup/provision_basedn_modify.ldif index 36e80ec69c..29ba75be98 100644 --- a/source4/setup/provision_basedn_modify.ldif +++ b/source4/setup/provision_basedn_modify.ldif @@ -67,9 +67,6 @@ fSMORoleOwner: CN=NTDS Settings,${SERVERDN} replace: systemFlags systemFlags: -1946157056 - -replace: isCriticalSystemObject -isCriticalSystemObject: TRUE -- replace: subRefs subRefs: ${CONFIGDN} - @@ -84,4 +81,7 @@ wellKnownObjects: B:32:a361b2ffffd211d1aa4b00c04fd7d83a:OU=Domain Controllers,${ wellKnownObjects: B:32:aa312825768811d1aded00c04fd8d5cd:CN=Computers,${DOMAINDN} wellKnownObjects: B:32:a9d1ca15768811d1aded00c04fd8d5cd:CN=Users,${DOMAINDN} - +replace: isCriticalSystemObject +isCriticalSystemObject: TRUE +- ${DOMAINGUID_MOD} diff --git a/source4/setup/provision_computers_modify.ldif b/source4/setup/provision_computers_modify.ldif index 110c44c356..b3d9dc1fa8 100644 --- a/source4/setup/provision_computers_modify.ldif +++ b/source4/setup/provision_computers_modify.ldif @@ -3,11 +3,11 @@ changetype: modify replace: description description: Default container for upgraded computer accounts - -replace: showInAdvancedViewOnly -showInAdvancedViewOnly: FALSE -- replace: systemFlags systemFlags: -1946157056 - replace: isCriticalSystemObject isCriticalSystemObject: TRUE +- +replace: showInAdvancedViewOnly +showInAdvancedViewOnly: FALSE diff --git a/source4/setup/provision_configuration.ldif b/source4/setup/provision_configuration.ldif index 0dad24c705..4109c2236c 100644 --- a/source4/setup/provision_configuration.ldif +++ b/source4/setup/provision_configuration.ldif @@ -8,6 +8,7 @@ cn: Partitions systemFlags: -2147483648 msDS-Behavior-Version: ${FOREST_FUNCTIONALALITY} fSMORoleOwner: CN=NTDS Settings,${SERVERDN} +showInAdvancedViewOnly: TRUE dn: CN=Enterprise Configuration,CN=Partitions,${CONFIGDN} objectClass: top diff --git a/source4/setup/provision_group_policy.ldif b/source4/setup/provision_group_policy.ldif index d6a4659250..65ab1eaf5f 100644 --- a/source4/setup/provision_group_policy.ldif +++ b/source4/setup/provision_group_policy.ldif @@ -1,14 +1,3 @@ -dn: CN=Default Domain Policy,CN=System,${DOMAINDN} -objectClass: top -objectClass: leaf -objectClass: domainPolicy -isCriticalSystemObject: TRUE - -dn: CN=AppCategories,CN=Default Domain Policy,CN=System,${DOMAINDN} -objectClass: top -objectClass: classStore -isCriticalSystemObject: TRUE - dn: CN={${POLICYGUID}},CN=Policies,CN=System,${DOMAINDN} objectClass: top objectClass: container diff --git a/source4/setup/provision_self_join.ldif b/source4/setup/provision_self_join.ldif index b60fea6576..da8c5b9e1d 100644 --- a/source4/setup/provision_self_join.ldif +++ b/source4/setup/provision_self_join.ldif @@ -15,7 +15,6 @@ sAMAccountName: ${NETBIOSNAME}$ operatingSystem: Samba operatingSystemVersion: ${SAMBA_VERSION_STRING} dNSHostName: ${DNSNAME} -isCriticalSystemObject: TRUE userPassword:: ${MACHINEPASS_B64} servicePrincipalName: HOST/${DNSNAME} servicePrincipalName: HOST/${NETBIOSNAME} @@ -23,6 +22,7 @@ servicePrincipalName: HOST/${DNSNAME}/${REALM} servicePrincipalName: HOST/${NETBIOSNAME}/${REALM} servicePrincipalName: HOST/${DNSNAME}/${DOMAIN} servicePrincipalName: HOST/${NETBIOSNAME}/${DOMAIN} +isCriticalSystemObject: TRUE #Provide a account for DNS keytab export dn: CN=dns,CN=Users,${DOMAINDN} @@ -36,9 +36,8 @@ userAccountControl: 514 accountExpires: 9223372036854775807 sAMAccountName: dns servicePrincipalName: DNS/${DNSDOMAIN} -isCriticalSystemObject: TRUE userPassword:: ${DNSPASS_B64} -showInAdvancedViewOnly: TRUE +isCriticalSystemObject: TRUE dn: ${SERVERDN} objectClass: top diff --git a/source4/setup/provision_users.ldif b/source4/setup/provision_users.ldif index 88146d8cac..47240a9d07 100644 --- a/source4/setup/provision_users.ldif +++ b/source4/setup/provision_users.ldif @@ -7,8 +7,8 @@ objectSid: ${DOMAINSID}-500 adminCount: 1 accountExpires: 9223372036854775807 sAMAccountName: Administrator -isCriticalSystemObject: TRUE userPassword:: ${ADMINPASS_B64} +isCriticalSystemObject: TRUE dn: CN=Guest,CN=Users,${DOMAINDN} objectClass: user @@ -45,8 +45,8 @@ adminCount: 1 accountExpires: 9223372036854775807 sAMAccountName: krbtgt servicePrincipalName: kadmin/changepw -isCriticalSystemObject: TRUE userPassword:: ${KRBTGTPASS_B64} +isCriticalSystemObject: TRUE dn: CN=Domain Computers,CN=Users,${DOMAINDN} objectClass: top @@ -187,16 +187,6 @@ sAMAccountName: Event Log Readers groupType: -2147483644 isCriticalSystemObject: TRUE -dn: CN=IIS_IUSRS,CN=Users,${DOMAINDN} -objectClass: top -objectClass: group -cn: IIS_IUSRS -description: IIS_IUSRS -objectSid: ${DOMAINSID}-568 -sAMAccountName: IIS_IUSRS -groupType: -2147483644 -isCriticalSystemObject: TRUE - dn: CN=Administrators,CN=Builtin,${DOMAINDN} objectClass: top objectClass: group @@ -210,7 +200,6 @@ adminCount: 1 sAMAccountName: Administrators systemFlags: -1946157056 groupType: -2147483643 -isCriticalSystemObject: TRUE privilege: SeSecurityPrivilege privilege: SeBackupPrivilege privilege: SeRestorePrivilege @@ -235,6 +224,7 @@ privilege: SeEnableDelegationPrivilege privilege: SeInteractiveLogonRight privilege: SeNetworkLogonRight privilege: SeRemoteInteractiveLogonRight +isCriticalSystemObject: TRUE dn: CN=Users,CN=Builtin,${DOMAINDN} objectClass: top @@ -271,10 +261,10 @@ adminCount: 1 sAMAccountName: Print Operators systemFlags: -1946157056 groupType: -2147483643 -isCriticalSystemObject: TRUE privilege: SeLoadDriverPrivilege privilege: SeShutdownPrivilege privilege: SeInteractiveLogonRight +isCriticalSystemObject: TRUE dn: CN=Backup Operators,CN=Builtin,${DOMAINDN} objectClass: top @@ -286,11 +276,11 @@ adminCount: 1 sAMAccountName: Backup Operators systemFlags: -1946157056 groupType: -2147483643 -isCriticalSystemObject: TRUE privilege: SeBackupPrivilege privilege: SeRestorePrivilege privilege: SeShutdownPrivilege privilege: SeInteractiveLogonRight +isCriticalSystemObject: TRUE dn: CN=Replicator,CN=Builtin,${DOMAINDN} objectClass: top @@ -358,13 +348,13 @@ adminCount: 1 sAMAccountName: Server Operators systemFlags: -1946157056 groupType: -2147483643 -isCriticalSystemObject: TRUE privilege: SeBackupPrivilege privilege: SeSystemtimePrivilege privilege: SeRemoteShutdownPrivilege privilege: SeRestorePrivilege privilege: SeShutdownPrivilege privilege: SeInteractiveLogonRight +isCriticalSystemObject: TRUE dn: CN=Account Operators,CN=Builtin,${DOMAINDN} objectClass: top @@ -376,8 +366,8 @@ adminCount: 1 sAMAccountName: Account Operators systemFlags: -1946157056 groupType: -2147483643 -isCriticalSystemObject: TRUE privilege: SeInteractiveLogonRight +isCriticalSystemObject: TRUE dn: CN=Pre-Windows 2000 Compatible Access,CN=Builtin,${DOMAINDN} objectClass: top @@ -388,9 +378,9 @@ objectSid: S-1-5-32-554 sAMAccountName: Pre-Windows 2000 Compatible Access systemFlags: -1946157056 groupType: -2147483643 -isCriticalSystemObject: TRUE privilege: SeRemoteInteractiveLogonRight privilege: SeChangeNotifyPrivilege +isCriticalSystemObject: TRUE dn: CN=Incoming Forest Trust Builders,CN=Builtin,${DOMAINDN} objectClass: top diff --git a/source4/setup/provision_users_modify.ldif b/source4/setup/provision_users_modify.ldif index a7e8a4336a..6a2e180b15 100644 --- a/source4/setup/provision_users_modify.ldif +++ b/source4/setup/provision_users_modify.ldif @@ -3,11 +3,11 @@ changetype: modify replace: description description: Default container for upgraded user accounts - -replace: showInAdvancedViewOnly -showInAdvancedViewOnly: FALSE -- replace: systemFlags systemFlags: -1946157056 - replace: isCriticalSystemObject isCriticalSystemObject: TRUE +- +replace: showInAdvancedViewOnly +showInAdvancedViewOnly: FALSE diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif index c11e65e465..591aefbb75 100644 --- a/source4/setup/schema_samba4.ldif +++ b/source4/setup/schema_samba4.ldif @@ -220,7 +220,6 @@ objectClass: classSchema subClassOf: top governsID: 1.3.6.1.4.1.7165.4.2.2 rDNAttID: cn -showInAdvancedViewOnly: TRUE adminDisplayName: Samba4-Local-Domain adminDescription: Samba4-Local-Domain systemMayContain: msDS-Behavior-Version @@ -243,7 +242,6 @@ subClassOf: top governsID: 1.3.6.1.4.1.7165.4.2.1 mayContain: msDS-ObjectReferenceBL rDNAttID: cn -showInAdvancedViewOnly: TRUE adminDisplayName: Samba4TopTop adminDescription: Attributes used in top in Samba4 that OpenLDAP does not objectClassCategory: 3 @@ -344,7 +342,6 @@ objectClass: classSchema subClassOf: top governsID: 1.3.6.1.4.1.7165.4.2.3 rDNAttID: cn -showInAdvancedViewOnly: TRUE adminDisplayName: Samba4TopExtra adminDescription: Attributes used in top in Samba4 that OpenLDAP does not objectClassCategory: 2 -- cgit From 09135ee5a09a8b6aabf88c1bdf9280065c8b35e7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 18 Jul 2009 10:15:55 +1000 Subject: s4:kdc Add in a simple check for constrained delegation to self To do this properly, we must use the PAC, but for now this is enough to check that we are delegating to another name on the same host (which must be safe). (Windows 7 does this a lot, also noted in bug 6273) Andrew Bartlett --- source4/kdc/hdb-samba4.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 435282a0c1..cadbe33af6 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -1422,6 +1422,75 @@ static krb5_error_code hdb_samba4_destroy(krb5_context context, HDB *db) return 0; } +krb5_error_code hdb_samba4_check_constrained_delegation(krb5_context context, HDB *db, + hdb_entry_ex *entry, + krb5_const_principal target_principal) +{ + struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db; + struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(ldb_ctx, "loadparm"), + struct loadparm_context); + krb5_error_code ret; + krb5_principal enterprise_prinicpal = NULL; + struct ldb_dn *realm_dn; + struct ldb_message *msg; + struct dom_sid *orig_sid; + struct dom_sid *target_sid; + struct hdb_ldb_private *p = talloc_get_type(entry->ctx, struct hdb_ldb_private); + const char *delegation_check_attrs[] = { + "objectSid", NULL + }; + + TALLOC_CTX *mem_ctx = talloc_named(db, 0, "hdb_samba4_check_constrained_delegation"); + + if (!mem_ctx) { + ret = ENOMEM; + krb5_set_error_message(context, ret, "hdb_samba4_fetch: talloc_named() failed!"); + return ret; + } + + if (target_principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) { + /* Need to reparse the enterprise principal to find the real target */ + if (target_principal->name.name_string.len != 1) { + ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, "hdb_samba4_check_constrained_delegation: request for delegation to enterprise principal with wrong (%d) number of components", + target_principal->name.name_string.len); + talloc_free(mem_ctx); + return ret; + } + ret = krb5_parse_name(context, target_principal->name.name_string.val[0], + &enterprise_prinicpal); + if (ret) { + talloc_free(mem_ctx); + return ret; + } + target_principal = enterprise_prinicpal; + } + + ret = hdb_samba4_lookup_server(context, db, lp_ctx, mem_ctx, target_principal, + delegation_check_attrs, &realm_dn, &msg); + + krb5_free_principal(context, enterprise_prinicpal); + + if (ret != 0) { + talloc_free(mem_ctx); + return ret; + } + + orig_sid = samdb_result_dom_sid(mem_ctx, p->msg, "objectSid"); + target_sid = samdb_result_dom_sid(mem_ctx, msg, "objectSid"); + + /* Allow delegation to the same principal, even if by a different + * name. The easy and safe way to prove this is by SID + * comparison */ + if (!(orig_sid && target_sid && dom_sid_equal(orig_sid, target_sid))) { + talloc_free(mem_ctx); + return KRB5KDC_ERR_BADOPTION; + } + + talloc_free(mem_ctx); + return ret; +} + /* This interface is to be called by the KDC, which is expecting Samba * calling conventions. It is also called by a wrapper * (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb @@ -1486,7 +1555,7 @@ NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx, (*db)->hdb_destroy = hdb_samba4_destroy; (*db)->hdb_auth_status = NULL; - (*db)->hdb_check_constrained_delegation = NULL; + (*db)->hdb_check_constrained_delegation = hdb_samba4_check_constrained_delegation; return NT_STATUS_OK; } -- cgit From c80783eafd28bb3d749761cbbed80423c908d247 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 20 Jul 2009 10:25:25 +0200 Subject: Re-add accidently removed shares test. --- source4/scripting/python/samba/tests/shares.py | 74 ++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 source4/scripting/python/samba/tests/shares.py diff --git a/source4/scripting/python/samba/tests/shares.py b/source4/scripting/python/samba/tests/shares.py new file mode 100644 index 0000000000..9130c36780 --- /dev/null +++ b/source4/scripting/python/samba/tests/shares.py @@ -0,0 +1,74 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. Tests for shares +# Copyright (C) Jelmer Vernooij 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 . +# +from samba.shares import SharesContainer +from unittest import TestCase + + +class MockService(object): + + def __init__(self, data): + self.data = data + + def __getitem__(self, name): + return self.data[name] + + +class MockLoadParm(object): + + def __init__(self, data): + self.data = data + + def __getitem__(self, name): + return MockService(self.data[name]) + + def __contains__(self, name): + return name in self.data + + def __len__(self): + return len(self.data) + + def services(self): + return self.data.keys() + + +class ShareTests(TestCase): + + def _get_shares(self, conf): + return SharesContainer(MockLoadParm(conf)) + + def test_len_no_global(self): + shares = self._get_shares({}) + self.assertEquals(0, len(shares)) + + def test_iter(self): + self.assertEquals([], list(self._get_shares({}))) + self.assertEquals([], list(self._get_shares({"global":{}}))) + self.assertEquals(["bla"], list(self._get_shares({"global":{}, "bla":{}}))) + + def test_len(self): + shares = self._get_shares({"global": {}}) + self.assertEquals(0, len(shares)) + + def test_getitem_nonexistant(self): + shares = self._get_shares({"global": {}}) + self.assertRaises(KeyError, shares.__getitem__, "bla") + + def test_getitem_global(self): + shares = self._get_shares({"global": {}}) + self.assertRaises(KeyError, shares.__getitem__, "global") -- cgit From 54a51839ea65aa788b18fce8de0ae4f9ba63e4e7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 18 Jul 2009 15:28:58 +0930 Subject: Make tdb transaction lock recursive (samba version) This patch replaces 6ed27edbcd3ba1893636a8072c8d7a621437daf7 and 1a416ff13ca7786f2e8d24c66addf00883e9cb12, which fixed the bug where traversals inside transactions would release the transaction lock early. This solution is more general, and solves the more minor symptom that nested traversals would also release the transaction lock early. (It was also suggestd in Volker's comment in 6ed27ed). This patch also applies to ctdb, if the traverse.c part is removed (ctdb's tdb code never received the previous two fixes). Tested using the testsuite from ccan (adapted to the samba code). Thanks to Michael Adam for feedback. Signed-off-by: Rusty Russell Signed-off-by: Michael Adam --- lib/tdb/common/lock.c | 17 +++++++++++++---- lib/tdb/common/tdb_private.h | 2 +- lib/tdb/common/traverse.c | 22 ++++++---------------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/lib/tdb/common/lock.c b/lib/tdb/common/lock.c index f156c0fa7b..d812fbfdc5 100644 --- a/lib/tdb/common/lock.c +++ b/lib/tdb/common/lock.c @@ -301,16 +301,21 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype) */ int tdb_transaction_lock(struct tdb_context *tdb, int ltype) { - if (tdb->have_transaction_lock || tdb->global_lock.count) { + if (tdb->global_lock.count) { + return 0; + } + if (tdb->transaction_lock_count > 0) { + tdb->transaction_lock_count++; return 0; } + if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype, F_SETLKW, 0, 1) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n")); tdb->ecode = TDB_ERR_LOCK; return -1; } - tdb->have_transaction_lock = 1; + tdb->transaction_lock_count++; return 0; } @@ -320,12 +325,16 @@ int tdb_transaction_lock(struct tdb_context *tdb, int ltype) int tdb_transaction_unlock(struct tdb_context *tdb) { int ret; - if (!tdb->have_transaction_lock) { + if (tdb->global_lock.count) { + return 0; + } + if (tdb->transaction_lock_count > 0) { + tdb->transaction_lock_count--; return 0; } ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); if (ret == 0) { - tdb->have_transaction_lock = 0; + tdb->transaction_lock_count = 0; } return ret; } diff --git a/lib/tdb/common/tdb_private.h b/lib/tdb/common/tdb_private.h index ffac89ff0e..45b85f4c93 100644 --- a/lib/tdb/common/tdb_private.h +++ b/lib/tdb/common/tdb_private.h @@ -166,7 +166,7 @@ struct tdb_context { struct tdb_transaction *transaction; int page_size; int max_dead_records; - bool have_transaction_lock; + int transaction_lock_count; volatile sig_atomic_t *interrupt_sig_ptr; }; diff --git a/lib/tdb/common/traverse.c b/lib/tdb/common/traverse.c index 69c81e6e98..07b0c23858 100644 --- a/lib/tdb/common/traverse.c +++ b/lib/tdb/common/traverse.c @@ -204,23 +204,18 @@ int tdb_traverse_read(struct tdb_context *tdb, { struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; int ret; - bool in_transaction = (tdb->transaction != NULL); /* we need to get a read lock on the transaction lock here to cope with the lock ordering semantics of solaris10 */ - if (!in_transaction) { - if (tdb_transaction_lock(tdb, F_RDLCK)) { - return -1; - } + if (tdb_transaction_lock(tdb, F_RDLCK)) { + return -1; } tdb->traverse_read++; ret = tdb_traverse_internal(tdb, fn, private_data, &tl); tdb->traverse_read--; - if (!in_transaction) { - tdb_transaction_unlock(tdb); - } + tdb_transaction_unlock(tdb); return ret; } @@ -237,25 +232,20 @@ int tdb_traverse(struct tdb_context *tdb, { struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; int ret; - bool in_transaction = (tdb->transaction != NULL); if (tdb->read_only || tdb->traverse_read) { return tdb_traverse_read(tdb, fn, private_data); } - if (!in_transaction) { - if (tdb_transaction_lock(tdb, F_WRLCK)) { - return -1; - } + if (tdb_transaction_lock(tdb, F_WRLCK)) { + return -1; } tdb->traverse_write++; ret = tdb_traverse_internal(tdb, fn, private_data, &tl); tdb->traverse_write--; - if (!in_transaction) { - tdb_transaction_unlock(tdb); - } + tdb_transaction_unlock(tdb); return ret; } -- cgit From 93570491712bf42b5c8dba825e7d2a40e71c0378 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Jul 2009 15:15:08 -0700 Subject: Make cli_send_mailslot() static. Preparing to do away with unexpected.tdb.... Jeremy. --- source3/include/proto.h | 7 ------- source3/libsmb/clidgram.c | 3 +-- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index d68aa4b619..695e14b53c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2270,13 +2270,6 @@ bool cli_resolve_path(TALLOC_CTX *ctx, /* The following definitions come from libsmb/clidgram.c */ -bool cli_send_mailslot(struct messaging_context *msg_ctx, - bool unique, const char *mailslot, - uint16 priority, - char *buf, int len, - const char *srcname, int src_type, - const char *dstname, int dest_type, - const struct sockaddr_storage *dest_ss); bool send_getdc_request(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx, struct sockaddr_storage *dc_ss, diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 349a8331b4..f5dbd72f22 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -25,7 +25,7 @@ * cli_send_mailslot, send a mailslot for client code ... */ -bool cli_send_mailslot(struct messaging_context *msg_ctx, +static bool cli_send_mailslot(struct messaging_context *msg_ctx, bool unique, const char *mailslot, uint16 priority, char *buf, int len, @@ -309,4 +309,3 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, return True; } - -- cgit From 04c3dfde0f0bc12daf0922a0fe578e3bde587fc8 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 20 Jul 2009 15:37:18 -0700 Subject: lib util: Fix const warning --- 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 c51f9384b8..5b8456547a 100644 --- a/lib/util/genrand.c +++ b/lib/util/genrand.c @@ -294,7 +294,7 @@ _PUBLIC_ uint32_t generate_random(void) _PUBLIC_ bool check_password_quality(const char *s) { int has_digit=0, has_capital=0, has_lower=0, has_special=0, has_high=0; - char* reals = s; + const char* reals = s; while (*s) { if (isdigit((unsigned char)*s)) { has_digit |= 1; -- cgit From 12a5db45e2814b6992210d8f30908ab3e8b6bc65 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 10:38:56 -0700 Subject: s3: Change file_structs to be allocated with talloc instead of malloc --- source3/smbd/files.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 0e6dd7e457..48d2288468 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -65,21 +65,26 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, return NT_STATUS_TOO_MANY_OPENED_FILES; } - fsp = SMB_MALLOC_P(files_struct); + /* + * Make a child of the connection_struct as an fsp can't exist + * indepenedent of a connection. + */ + fsp = talloc_zero(conn, struct files_struct); if (!fsp) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(fsp); - - fsp->fh = SMB_MALLOC_P(struct fd_handle); + /* + * This can't be a child of fsp because the file_handle can be ref'd + * when doing a dos/fcb open, which will then share the file_handle + * across multiple fsps. + */ + fsp->fh = talloc_zero(conn, struct fd_handle); if (!fsp->fh) { - SAFE_FREE(fsp); + TALLOC_FREE(fsp); return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(fsp->fh); - fsp->fh->ref_count = 1; fsp->fh->fd = -1; @@ -449,7 +454,7 @@ void file_free(struct smb_request *req, files_struct *fsp) TALLOC_FREE(fsp->fake_file_handle); if (fsp->fh->ref_count == 1) { - SAFE_FREE(fsp->fh); + TALLOC_FREE(fsp->fh); } else { fsp->fh->ref_count--; } @@ -495,7 +500,7 @@ void file_free(struct smb_request *req, files_struct *fsp) information */ ZERO_STRUCTP(fsp); - SAFE_FREE(fsp); + TALLOC_FREE(fsp); } /**************************************************************************** @@ -545,7 +550,7 @@ void dup_file_fsp(struct smb_request *req, files_struct *from, uint32 access_mask, uint32 share_access, uint32 create_options, files_struct *to) { - SAFE_FREE(to->fh); + TALLOC_FREE(to->fh); to->fh = from->fh; to->fh->ref_count++; -- cgit From 635e5e7ff038378d28c52bd5f81d24db99a77a76 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 11:50:30 -0700 Subject: s3 onefs oplocks: Replace static fstring with talloc'd dbg_ctx() --- source3/smbd/oplock_onefs.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c index d359f9c6f2..497cfc7b54 100644 --- a/source3/smbd/oplock_onefs.c +++ b/source3/smbd/oplock_onefs.c @@ -60,29 +60,29 @@ struct onefs_callback_record { struct onefs_callback_record *callback_recs; /** - * Convert a onefs_callback_record to a string. + * Convert a onefs_callback_record to a debug string using the dbg_ctx(). */ -static char *onefs_callback_record_str_static(const struct onefs_callback_record *r) +const char *onefs_cb_record_str_dbg(const struct onefs_callback_record *r) { - static fstring result; + char *result; if (r == NULL) { - fstrcpy(result, "NULL callback record"); + result = talloc_strdup(dbg_ctx(), "NULL callback record"); return result; } switch (r->state) { case ONEFS_OPEN_FILE: - fstr_sprintf(result, "cb record %llu for file %s", - r->id, r->data.fsp->fsp_name); - break; + result = talloc_asprintf(dbg_ctx(), "cb record %llu for file " + "%s", r->id, r->data.fsp->fsp_name); case ONEFS_WAITING_FOR_OPLOCK: - fstr_sprintf(result, "cb record %llu for pending mid %d", - r->id, (int)r->data.mid); + result = talloc_asprintf(dbg_ctx(), "cb record %llu for " + "pending mid %d", r->id, + (int)r->data.mid); break; default: - fstr_sprintf(result, "cb record %llu unknown state %d", - r->id, r->state); + result = talloc_asprintf(dbg_ctx(), "cb record %llu unknown " + "state %d", r->id, r->state); break; } @@ -102,7 +102,7 @@ static void debug_cb_records(const char *fn) DEBUG(10, ("cb records (%s):\n", fn)); for (rec = callback_recs; rec; rec = rec->next) { - DEBUGADD(10, ("%s\n", onefs_callback_record_str_static(rec))); + DEBUGADD(10, ("%s\n", onefs_cb_record_dbg_str(rec))); } } @@ -127,7 +127,7 @@ static struct onefs_callback_record *onefs_find_cb(uint64_t id, for (rec = callback_recs; rec; rec = rec->next) { if (rec->id == id) { DEBUG(10, ("found %s\n", - onefs_callback_record_str_static(rec))); + onefs_cb_record_dbg_str(rec))); break; } } @@ -139,7 +139,7 @@ static struct onefs_callback_record *onefs_find_cb(uint64_t id, if (rec->state != expected_state) { DEBUG(0, ("Expected cb type %d, got %s", expected_state, - onefs_callback_record_str_static(rec))); + onefs_cb_record_dbg_str(rec))); SMB_ASSERT(0); return NULL; } @@ -413,7 +413,7 @@ static void semlock_available_handler(uint64_t id) char *msg; if (asprintf(&msg, "Semlock available on an open that wasn't " "deferred: %s\n", - onefs_callback_record_str_static(cb)) != -1) { + onefs_cb_record_dbg_str(cb)) != -1) { smb_panic(msg); } smb_panic("Semlock available on an open that wasn't " @@ -457,7 +457,7 @@ static void semlock_async_failure_handler(uint64_t id) char *msg; if (asprintf(&msg, "Semlock failure on an open that wasn't " "deferred: %s\n", - onefs_callback_record_str_static(cb)) != -1) { + onefs_cb_record_dbg_str(cb)) != -1) { smb_panic(msg); } smb_panic("Semlock failure on an open that wasn't deferred\n"); -- cgit From 5a8d70d465f28ae02f4df7a3c2905e028c2e3142 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 14:50:37 -0700 Subject: s3: Change fsp->fsp_name to be an smb_filename struct! --- source3/include/proto.h | 5 +- source3/include/smb.h | 2 +- source3/locking/brlock.c | 4 +- source3/locking/locking.c | 29 +++--- source3/locking/posix.c | 37 ++++--- source3/smbd/aio.c | 28 ++--- source3/smbd/blocking.c | 15 +-- source3/smbd/close.c | 163 +++++++++++++---------------- source3/smbd/dosmode.c | 2 +- source3/smbd/fileio.c | 57 +++++----- source3/smbd/files.c | 73 ++++++++++--- source3/smbd/ipc.c | 2 +- source3/smbd/notify.c | 7 +- source3/smbd/nttrans.c | 20 ++-- source3/smbd/open.c | 74 +++++++------ source3/smbd/oplock.c | 24 +++-- source3/smbd/oplock_irix.c | 13 ++- source3/smbd/oplock_linux.c | 9 +- source3/smbd/oplock_onefs.c | 11 +- source3/smbd/pipes.c | 19 +++- source3/smbd/posix_acls.c | 247 ++++++++++++++++++++------------------------ source3/smbd/reply.c | 139 ++++++++++--------------- source3/smbd/smb2_close.c | 2 +- source3/smbd/smb2_create.c | 19 ++-- source3/smbd/smb2_flush.c | 2 +- source3/smbd/smb2_getinfo.c | 29 ++---- source3/smbd/smb2_notify.c | 2 +- source3/smbd/smb2_read.c | 4 +- source3/smbd/smb2_setinfo.c | 25 ++--- source3/smbd/smb2_write.c | 6 +- source3/smbd/trans2.c | 70 ++++++------- source3/smbd/vfs.c | 36 ++++--- 32 files changed, 585 insertions(+), 590 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 695e14b53c..830d2284c4 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6365,9 +6365,12 @@ void file_sync_all(connection_struct *conn); void file_free(struct smb_request *req, files_struct *fsp); files_struct *file_fnum(uint16 fnum); files_struct *file_fsp(struct smb_request *req, uint16 fid); -void dup_file_fsp(struct smb_request *req, files_struct *from, +NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, uint32 access_mask, uint32 share_access, uint32 create_options, files_struct *to); +const char *fsp_str_dbg(const struct files_struct *fsp); +NTSTATUS fsp_set_smb_fname(struct files_struct *fsp, + const struct smb_filename *smb_fname_in); /* The following definitions come from smbd/ipc.c */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 2e9cf1b54a..94ed2186fb 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -452,7 +452,7 @@ typedef struct files_struct { bool lockdb_clean; bool initial_delete_on_close; /* Only set at NTCreateX if file was created. */ bool posix_open; - char *fsp_name; + struct smb_filename *fsp_name; struct vfs_fsp_data *vfs_extension; struct fake_file_handle *fake_file_handle; diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index be2948c531..e238ec959b 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1196,7 +1196,7 @@ bool brl_locktest(struct byte_range_lock *br_lck, DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n", (double)start, (double)size, ret ? "locked" : "unlocked", - fsp->fnum, fsp->fsp_name )); + fsp->fnum, fsp_str_dbg(fsp))); /* We need to return the inverse of is_posix_locked. */ ret = !ret; @@ -1262,7 +1262,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n", (double)*pstart, (double)*psize, ret ? "locked" : "unlocked", - fsp->fnum, fsp->fsp_name )); + fsp->fnum, fsp_str_dbg(fsp))); if (ret) { /* Hmmm. No clue what to set smbpid to - use -1. */ diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 91fe137fdc..fba871c704 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -109,11 +109,11 @@ bool strict_lock_default(files_struct *fsp, struct lock_struct *plock) if (strict_locking == Auto) { if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) { - DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name )); + DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp))); ret = True; } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) && (plock->lock_type == READ_LOCK)) { - DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); + DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp))); ret = True; } else { struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp); @@ -149,7 +149,7 @@ bool strict_lock_default(files_struct *fsp, struct lock_struct *plock) lock_flav_name(plock->lock_flav), (double)plock->start, (double)plock->size, ret ? "unlocked" : "locked", - plock->fnum, fsp->fsp_name )); + plock->fnum, fsp_str_dbg(fsp))); return ret; } @@ -259,7 +259,7 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, "blocking_lock=%s requested for fnum %d file %s\n", lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, blocking_lock ? "true" : - "false", fsp->fnum, fsp->fsp_name)); + "false", fsp->fnum, fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { @@ -308,7 +308,8 @@ NTSTATUS do_unlock(struct messaging_context *msg_ctx, } DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", - (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); + (double)offset, (double)count, fsp->fnum, + fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { @@ -358,7 +359,8 @@ NTSTATUS do_lock_cancel(files_struct *fsp, } DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n", - (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); + (double)offset, (double)count, fsp->fnum, + fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { @@ -1311,7 +1313,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, !lp_delete_readonly(SNUM(fsp->conn))) { DEBUG(10,("can_set_delete_on_close: file %s delete on close " "flag set but file attribute is readonly.\n", - fsp->fsp_name )); + fsp_str_dbg(fsp))); return NT_STATUS_CANNOT_DELETE; } @@ -1322,7 +1324,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, if (!CAN_WRITE(fsp->conn)) { DEBUG(10,("can_set_delete_on_close: file %s delete on " "close flag set but write access denied on share.\n", - fsp->fsp_name )); + fsp_str_dbg(fsp))); return NT_STATUS_ACCESS_DENIED; } @@ -1334,13 +1336,15 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, if (!(fsp->access_mask & DELETE_ACCESS)) { DEBUG(10,("can_set_delete_on_close: file %s delete on " "close flag set but delete access denied.\n", - fsp->fsp_name )); + fsp_str_dbg(fsp))); return NT_STATUS_ACCESS_DENIED; } /* Don't allow delete on close for non-empty directories. */ if (fsp->is_directory) { - return can_delete_directory(fsp->conn, fsp->fsp_name); + SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name)); + return can_delete_directory(fsp->conn, + fsp->fsp_name->base_name); } return NT_STATUS_OK; @@ -1422,7 +1426,7 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USE DEBUG(10,("set_delete_on_close: %s delete on close flag for " "fnum = %d, file %s\n", delete_on_close ? "Adding" : "Removing", fsp->fnum, - fsp->fsp_name )); + fsp_str_dbg(fsp))); lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL); @@ -1443,7 +1447,8 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USE set_delete_on_close_lck(lck, delete_on_close, tok); if (fsp->is_directory) { - send_stat_cache_delete_message(fsp->fsp_name); + SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name)); + send_stat_cache_delete_message(fsp->fsp_name->base_name); } TALLOC_FREE(lck); diff --git a/source3/locking/posix.c b/source3/locking/posix.c index 9b51c3aa6a..33ffaf95ca 100644 --- a/source3/locking/posix.c +++ b/source3/locking/posix.c @@ -280,8 +280,9 @@ bool is_posix_locked(files_struct *fsp, SMB_OFF_T count; int posix_lock_type = map_posix_lock_type(fsp,*plock_type); - DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n", - fsp->fsp_name, (double)*pu_offset, (double)*pu_count, posix_lock_type_name(*plock_type) )); + DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, " + "type = %s\n", fsp_str_dbg(fsp), (double)*pu_offset, + (double)*pu_count, posix_lock_type_name(*plock_type))); /* * If the requested lock won't fit in the POSIX range, we will @@ -424,7 +425,7 @@ static void increment_windows_lock_ref_count(files_struct *fsp) TALLOC_FREE(rec); DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n", - fsp->fsp_name, lock_ref_count )); + fsp_str_dbg(fsp), lock_ref_count)); } /**************************************************************************** @@ -460,7 +461,7 @@ void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount) TALLOC_FREE(rec); DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n", - fsp->fsp_name, lock_ref_count )); + fsp_str_dbg(fsp), lock_ref_count)); } static void decrement_windows_lock_ref_count(files_struct *fsp) @@ -492,7 +493,7 @@ static int get_windows_lock_ref_count(files_struct *fsp) } DEBUG(10,("get_windows_lock_count for file %s = %d\n", - fsp->fsp_name, lock_ref_count )); + fsp_str_dbg(fsp), lock_ref_count)); return lock_ref_count; } @@ -518,7 +519,7 @@ static void delete_windows_lock_ref_count(files_struct *fsp) TALLOC_FREE(rec); DEBUG(10,("delete_windows_lock_ref_count for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); } /**************************************************************************** @@ -555,7 +556,7 @@ static void add_fd_to_close_entry(files_struct *fsp) TALLOC_FREE(rec); DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n", - fsp->fh->fd, fsp->fsp_name )); + fsp->fh->fd, fsp_str_dbg(fsp))); } /**************************************************************************** @@ -945,8 +946,10 @@ bool set_posix_lock_windows_flavour(files_struct *fsp, struct lock_list *llist = NULL; struct lock_list *ll = NULL; - DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n", - fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) )); + DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, " + "count = %.0f, type = %s\n", fsp_str_dbg(fsp), + (double)u_offset, (double)u_count, + posix_lock_type_name(lock_type))); /* * If the requested lock won't fit in the POSIX range, we will @@ -1079,8 +1082,9 @@ bool release_posix_lock_windows_flavour(files_struct *fsp, struct lock_list *ulist = NULL; struct lock_list *ul = NULL; - DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f\n", - fsp->fsp_name, (double)u_offset, (double)u_count )); + DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, " + "count = %.0f\n", fsp_str_dbg(fsp), + (double)u_offset, (double)u_count)); /* Remember the number of Windows locks we have on this dev/ino pair. */ decrement_windows_lock_ref_count(fsp); @@ -1197,8 +1201,10 @@ bool set_posix_lock_posix_flavour(files_struct *fsp, SMB_OFF_T count; int posix_lock_type = map_posix_lock_type(fsp,lock_type); - DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n", - fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) )); + DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count " + "= %.0f, type = %s\n", fsp_str_dbg(fsp), + (double)u_offset, (double)u_count, + posix_lock_type_name(lock_type))); /* * If the requested lock won't fit in the POSIX range, we will @@ -1241,8 +1247,9 @@ bool release_posix_lock_posix_flavour(files_struct *fsp, struct lock_list *ulist = NULL; struct lock_list *ul = NULL; - DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f\n", - fsp->fsp_name, (double)u_offset, (double)u_count )); + DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, " + "count = %.0f\n", fsp_str_dbg(fsp), + (double)u_offset, (double)u_count)); /* * If the requested lock won't fit in the POSIX range, we will diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index c6f700f17a..ed415c5e13 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -188,7 +188,7 @@ bool schedule_aio_read_and_X(connection_struct *conn, DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, " "offset %.0f, len = %u (mid = %u)\n", - fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt, + fsp_str_dbg(fsp), (double)startpos, (unsigned int)smb_maxcnt, (unsigned int)aio_ex->req->mid )); outstanding_aio_calls++; @@ -241,7 +241,7 @@ bool schedule_aio_write_and_X(connection_struct *conn, DEBUG(10,("schedule_aio_write_and_X: failed to schedule " "aio_write for file %s, offset %.0f, len = %u " "(mid = %u)\n", - fsp->fsp_name, (double)startpos, + fsp_str_dbg(fsp), (double)startpos, (unsigned int)numtowrite, (unsigned int)req->mid )); return False; @@ -300,14 +300,14 @@ bool schedule_aio_write_and_X(connection_struct *conn, "failed."); } DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write " - "behind for file %s\n", fsp->fsp_name )); + "behind for file %s\n", fsp_str_dbg(fsp))); } outstanding_aio_calls++; DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write for file " "%s, offset %.0f, len = %u (mid = %u) " "outstanding_aio_calls = %d\n", - fsp->fsp_name, (double)startpos, (unsigned int)numtowrite, + fsp_str_dbg(fsp), (double)startpos, (unsigned int)numtowrite, (unsigned int)aio_ex->req->mid, outstanding_aio_calls )); return True; @@ -341,7 +341,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) DEBUG( 3,( "handle_aio_read_complete: file %s nread == -1. " "Error = %s\n", - aio_ex->fsp->fsp_name, strerror(errno) )); + fsp_str_dbg(aio_ex->fsp), strerror(errno))); ret = errno; ERROR_NT(map_nt_error_from_unix(ret)); @@ -359,7 +359,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) DEBUG( 3, ( "handle_aio_read_complete file %s max=%d " "nread=%d\n", - aio_ex->fsp->fsp_name, + fsp_str_dbg(aio_ex->fsp), (int)aio_ex->acb.aio_nbytes, (int)nread ) ); } @@ -374,7 +374,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) DEBUG(10,("handle_aio_read_complete: scheduled aio_read completed " "for file %s, offset %.0f, len = %u\n", - aio_ex->fsp->fsp_name, (double)aio_ex->acb.aio_offset, + fsp_str_dbg(aio_ex->fsp), (double)aio_ex->acb.aio_offset, (unsigned int)nread )); return ret; @@ -399,13 +399,13 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) DEBUG(5,("handle_aio_write_complete: " "aio_write_behind failed ! File %s " "is corrupt ! Error %s\n", - fsp->fsp_name, strerror(errno) )); + fsp_str_dbg(fsp), strerror(errno))); ret = errno; } else { DEBUG(0,("handle_aio_write_complete: " "aio_write_behind failed ! File %s " "is corrupt ! Wanted %u bytes but " - "only wrote %d\n", fsp->fsp_name, + "only wrote %d\n", fsp_str_dbg(fsp), (unsigned int)numtowrite, (int)nwritten )); ret = EIO; @@ -413,7 +413,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) } else { DEBUG(10,("handle_aio_write_complete: " "aio_write_behind completed for file %s\n", - fsp->fsp_name )); + fsp_str_dbg(fsp))); } return 0; } @@ -424,7 +424,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) if(nwritten == -1) { DEBUG( 3,( "handle_aio_write: file %s wanted %u bytes. " "nwritten == %d. Error = %s\n", - fsp->fsp_name, (unsigned int)numtowrite, + fsp_str_dbg(fsp), (unsigned int)numtowrite, (int)nwritten, strerror(errno) )); /* If errno is ECANCELED then don't return anything to the @@ -456,7 +456,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) ERRHRD, ERRdiskfull); srv_set_message(outbuf,0,0,true); DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); } aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nwritten; @@ -472,7 +472,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) DEBUG(10,("handle_aio_write_complete: scheduled aio_write completed " "for file %s, offset %.0f, requested %u, written = %u\n", - fsp->fsp_name, (double)aio_ex->acb.aio_offset, + fsp_str_dbg(fsp), (double)aio_ex->acb.aio_offset, (unsigned int)numtowrite, (unsigned int)nwritten )); return ret; @@ -496,7 +496,7 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr) if (SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb) == EINPROGRESS) { DEBUG(10,( "handle_aio_completed: operation mid %u still in " "process for file %s\n", - aio_ex->req->mid, aio_ex->fsp->fsp_name )); + aio_ex->req->mid, fsp_str_dbg(aio_ex->fsp))); return False; } diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 4c61428692..e752194ca5 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -202,7 +202,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n", (unsigned int)blr->expire_time.tv_sec, (unsigned int)blr->expire_time.tv_usec, lock_timeout, - blr->fsp->fnum, blr->fsp->fsp_name )); + blr->fsp->fnum, fsp_str_dbg(blr->fsp))); return True; } @@ -418,8 +418,9 @@ static bool process_lockingX(struct blocking_lock_record *blr) * Success - we got all the locks. */ - DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n", - fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) ); + DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d " + "num_locks=%d\n", fsp_str_dbg(fsp), fsp->fnum, + (unsigned int)locktype, num_locks)); reply_lockingX_success(blr); return True; @@ -442,7 +443,7 @@ static bool process_lockingX(struct blocking_lock_record *blr) DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \ Waiting....\n", - blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum)); + blr->lock_num, num_locks, fsp_str_dbg(fsp), fsp->fnum)); return False; } @@ -533,7 +534,7 @@ void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lo DEBUG(10, ("remove_pending_lock_requests_by_fid - removing " "request type %d for file %s fnum = %d\n", - blr->req->cmd, fsp->fsp_name, fsp->fnum)); + blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum)); blr_cancelled = blocking_lock_cancel(fsp, blr->lock_pid, @@ -583,7 +584,7 @@ void remove_pending_lock_requests_by_mid(int mid) if (br_lck) { DEBUG(10, ("remove_pending_lock_requests_by_mid - " "removing request type %d for file %s fnum " - "= %d\n", blr->req->cmd, fsp->fsp_name, + "= %d\n", blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum )); brl_lock_cancel(br_lck, @@ -703,7 +704,7 @@ void process_blocking_lock_queue(void) DEBUG(5,("process_blocking_lock_queue: " "pending lock fnum = %d for file %s " "timed out.\n", blr->fsp->fnum, - blr->fsp->fsp_name )); + fsp_str_dbg(blr->fsp))); brl_lock_cancel(br_lck, blr->lock_pid, diff --git a/source3/smbd/close.c b/source3/smbd/close.c index a0672f3949..f878aaa056 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -36,90 +36,102 @@ static NTSTATUS check_magic(struct files_struct *fsp) TALLOC_CTX *ctx = NULL; const char *p; struct connection_struct *conn = fsp->conn; + char *fname = NULL; + NTSTATUS status; if (!*lp_magicscript(SNUM(conn))) { return NT_STATUS_OK; } - DEBUG(5,("checking magic for %s\n",fsp->fsp_name)); + DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp))); + + ctx = talloc_stackframe(); + + status = get_full_smb_filename(ctx, fsp->fsp_name, &fname); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } - if (!(p = strrchr_m(fsp->fsp_name,'/'))) { - p = fsp->fsp_name; + if (!(p = strrchr_m(fname,'/'))) { + p = fname; } else { p++; } if (!strequal(lp_magicscript(SNUM(conn)),p)) { - return NT_STATUS_OK; + status = NT_STATUS_OK; + goto out; } - ctx = talloc_stackframe(); - if (*lp_magicoutput(SNUM(conn))) { magic_output = lp_magicoutput(SNUM(conn)); } else { magic_output = talloc_asprintf(ctx, "%s.out", - fsp->fsp_name); + fname); } if (!magic_output) { - TALLOC_FREE(ctx); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto out; } /* Ensure we don't depend on user's PATH. */ - p = talloc_asprintf(ctx, "./%s", fsp->fsp_name); + p = talloc_asprintf(ctx, "./%s", fname); if (!p) { - TALLOC_FREE(ctx); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto out; } - if (chmod(fsp->fsp_name,0755) == -1) { - TALLOC_FREE(ctx); - return map_nt_error_from_unix(errno); + if (chmod(fname, 0755) == -1) { + status = map_nt_error_from_unix(errno); + goto out; } ret = smbrun(p,&tmp_fd); DEBUG(3,("Invoking magic command %s gave %d\n", p,ret)); - unlink(fsp->fsp_name); + unlink(fname); if (ret != 0 || tmp_fd == -1) { if (tmp_fd != -1) { close(tmp_fd); } - TALLOC_FREE(ctx); - return NT_STATUS_UNSUCCESSFUL; + status = NT_STATUS_UNSUCCESSFUL; + goto out; } outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600); if (outfd == -1) { int err = errno; close(tmp_fd); - TALLOC_FREE(ctx); - return map_nt_error_from_unix(err); + status = map_nt_error_from_unix(err); + goto out; } if (sys_fstat(tmp_fd,&st) == -1) { int err = errno; close(tmp_fd); close(outfd); - TALLOC_FREE(ctx); - return map_nt_error_from_unix(err); + status = map_nt_error_from_unix(err); + goto out; } if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) { int err = errno; close(tmp_fd); close(outfd); - TALLOC_FREE(ctx); - return map_nt_error_from_unix(err); + status = map_nt_error_from_unix(err); + goto out; } close(tmp_fd); if (close(outfd) == -1) { - TALLOC_FREE(ctx); - return map_nt_error_from_unix(errno); + status = map_nt_error_from_unix(errno); + goto out; } + + status = NT_STATUS_OK; + + out: TALLOC_FREE(ctx); - return NT_STATUS_OK; + return status; } /**************************************************************************** @@ -261,18 +273,10 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, bool delete_file = false; bool changed_user = false; struct share_mode_lock *lck = NULL; - struct smb_filename *smb_fname = NULL; - char *fname = NULL; NTSTATUS status = NT_STATUS_OK; int ret; struct file_id id; - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - /* * Lock the share entries, and determine if we should delete * on close. If so delete whilst the lock is still in effect. @@ -284,7 +288,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, if (lck == NULL) { DEBUG(0, ("close_remove_share_mode: Could not get share mode " - "lock for file %s\n", smb_fname_str_dbg(smb_fname))); + "lock for file %s\n", fsp_str_dbg(fsp))); status = NT_STATUS_INVALID_PARAMETER; goto done; } @@ -296,7 +300,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, if (!del_share_mode(lck, fsp)) { DEBUG(0, ("close_remove_share_mode: Could not delete share " "entry for file %s\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); } if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) { @@ -354,7 +358,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, */ DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set " - "- deleting file.\n", smb_fname_str_dbg(smb_fname))); + "- deleting file.\n", fsp_str_dbg(fsp))); /* * Don't try to update the write time when we delete the file @@ -366,7 +370,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, DEBUG(5,("close_remove_share_mode: file %s. " "Change user to uid %u\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), (unsigned int)lck->delete_token->uid)); if (!push_sec_ctx()) { @@ -387,30 +391,30 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, hasn't been renamed. */ if (fsp->posix_open) { - ret = SMB_VFS_LSTAT(conn, smb_fname); + ret = SMB_VFS_LSTAT(conn, fsp->fsp_name); } else { - ret = SMB_VFS_STAT(conn, smb_fname); + ret = SMB_VFS_STAT(conn, fsp->fsp_name); } if (ret != 0) { DEBUG(5,("close_remove_share_mode: file %s. Delete on close " "was set and stat failed with error %s\n", - smb_fname_str_dbg(smb_fname), strerror(errno))); + fsp_str_dbg(fsp), strerror(errno))); /* * Don't save the errno here, we ignore this error */ goto done; } - id = vfs_file_id_from_sbuf(conn, &smb_fname->st); + id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st); if (!file_id_equal(&fsp->file_id, &id)) { DEBUG(5,("close_remove_share_mode: file %s. Delete on close " "was set and dev and/or inode does not match\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, " "stat file_id %s\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), file_id_string_tos(&id))); /* @@ -420,9 +424,9 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, } if ((conn->fs_capabilities & FILE_NAMED_STREAMS) - && !is_ntfs_stream_smb_fname(smb_fname)) { + && !is_ntfs_stream_smb_fname(fsp->fsp_name)) { - status = delete_all_streams(conn, smb_fname->base_name); + status = delete_all_streams(conn, fsp->fsp_name->base_name); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("delete_all_streams failed: %s\n", @@ -432,7 +436,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, } - if (SMB_VFS_UNLINK(conn, smb_fname) != 0) { + if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) { /* * This call can potentially fail as another smbd may * have had the file open with delete on close set and @@ -443,21 +447,14 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, DEBUG(5,("close_remove_share_mode: file %s. Delete on close " "was set and unlink failed with error %s\n", - smb_fname_str_dbg(smb_fname), strerror(errno))); + fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); } - status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - notify_fname(conn, NOTIFY_ACTION_REMOVED, FILE_NOTIFY_CHANGE_FILE_NAME, - fname); - - TALLOC_FREE(fname); + fsp->fsp_name->base_name); /* As we now have POSIX opens which can unlink * with other open files we may have taken @@ -476,7 +473,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, } TALLOC_FREE(lck); - TALLOC_FREE(smb_fname); return status; } @@ -499,7 +495,6 @@ void set_close_write_time(struct files_struct *fsp, struct timespec ts) static NTSTATUS update_write_time_on_close(struct files_struct *fsp) { - struct smb_filename *smb_fname = NULL; struct smb_file_time ft; NTSTATUS status; int ret = -1; @@ -514,43 +509,32 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp) fsp->close_write_time = timespec_current(); } - /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */ - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - /* Ensure we have a valid stat struct for the source. */ if (fsp->fh->fd != -1) { - ret = SMB_VFS_FSTAT(fsp, &smb_fname->st); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } else { if (fsp->posix_open) { - ret = SMB_VFS_LSTAT(fsp->conn, smb_fname); + ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { - ret = SMB_VFS_STAT(fsp->conn, smb_fname); + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); } } if (ret == -1) { - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } - if (!VALID_STAT(smb_fname->st)) { + if (!VALID_STAT(fsp->fsp_name->st)) { /* if it doesn't seem to be a real file */ - status = NT_STATUS_OK; - goto out; + return NT_STATUS_OK; } ft.mtime = fsp->close_write_time; - status = smb_set_file_time(fsp->conn, fsp, smb_fname, &ft, true); + status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, true); if (!NT_STATUS_IS_OK(status)) { - goto out; + return status; } - out: - TALLOC_FREE(smb_fname); return status; } @@ -647,7 +631,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, status = ntstatus_keeperror(status, tmp); DEBUG(2,("%s closed file %s (numopen=%d) %s\n", - conn->server_info->unix_name,fsp->fsp_name, + conn->server_info->unix_name, fsp_str_dbg(fsp), conn->num_files_open - 1, nt_errstr(status) )); @@ -663,16 +647,9 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, enum file_close_type close_type) { struct share_mode_lock *lck = NULL; - struct smb_filename *smb_dname = NULL; bool delete_dir = False; NTSTATUS status = NT_STATUS_OK; - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_dname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - /* * NT can set delete_on_close of the last open * reference to a directory also. @@ -683,14 +660,14 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, if (lck == NULL) { DEBUG(0, ("close_directory: Could not get share mode lock for " - "%s\n", smb_fname_str_dbg(smb_dname))); + "%s\n", fsp_str_dbg(fsp))); status = NT_STATUS_INVALID_PARAMETER; goto out; } if (!del_share_mode(lck, fsp)) { DEBUG(0, ("close_directory: Could not delete share entry for " - "%s\n", smb_fname_str_dbg(smb_dname))); + "%s\n", fsp_str_dbg(fsp))); } if (fsp->initial_delete_on_close) { @@ -704,7 +681,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, become_user(fsp->conn, fsp->vuid); became_user = True; } - send_stat_cache_delete_message(fsp->fsp_name); + send_stat_cache_delete_message(fsp->fsp_name->base_name); set_delete_on_close_lck(lck, True, ¤t_user.ut); if (became_user) { unbecome_user(); @@ -747,11 +724,12 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, TALLOC_FREE(lck); - status = rmdir_internals(talloc_tos(), fsp->conn, smb_dname); + status = rmdir_internals(talloc_tos(), fsp->conn, + fsp->fsp_name); DEBUG(5,("close_directory: %s. Delete on close was set - " "deleting directory returned %s.\n", - smb_fname_str_dbg(smb_dname), nt_errstr(status))); + fsp_str_dbg(fsp), nt_errstr(status))); /* unbecome user. */ pop_sec_ctx(); @@ -774,7 +752,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n", - smb_fname_str_dbg(smb_dname), fsp->fh->fd, errno, + fsp_str_dbg(fsp), fsp->fh->fd, errno, strerror(errno))); } @@ -786,7 +764,6 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, out: TALLOC_FREE(lck); - TALLOC_FREE(smb_dname); return status; } diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index d3df80ad91..bd0c7df959 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -845,7 +845,7 @@ bool update_write_time(struct files_struct *fsp) } notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name); + FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name); return true; } diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 60cef09b3b..bd609d3e86 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -103,7 +103,7 @@ tryagain: } DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n", - fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); + fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret)); fsp->fh->pos += ret; fsp->fh->position_information = fsp->fh->pos; @@ -136,7 +136,7 @@ static ssize_t real_write_file(struct smb_request *req, } DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n", - fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); + fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret)); if (ret != -1) { fsp->fh->pos += ret; @@ -164,8 +164,9 @@ static int wcp_file_size_change(files_struct *fsp) wcp->file_size = wcp->offset + wcp->data_size; ret = SMB_VFS_FTRUNCATE(fsp, wcp->file_size); if (ret == -1) { - DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n", - fsp->fsp_name, (double)wcp->file_size, strerror(errno) )); + DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f " + "error %s\n", fsp_str_dbg(fsp), + (double)wcp->file_size, strerror(errno))); } return ret; } @@ -179,7 +180,7 @@ static void update_write_time_handler(struct event_context *ctx, /* Remove the timed event handler. */ TALLOC_FREE(fsp->update_write_time_event); - DEBUG(5, ("Update write time on %s\n", fsp->fsp_name)); + DEBUG(5, ("Update write time on %s\n", fsp_str_dbg(fsp))); /* change the write time if not already changed by someone else */ update_write_time(fsp); @@ -244,7 +245,8 @@ void trigger_write_time_update_immediate(struct files_struct *fsp) } TALLOC_FREE(fsp->update_write_time_event); - DEBUG(5, ("Update write time immediate on %s\n", fsp->fsp_name)); + DEBUG(5, ("Update write time immediate on %s\n", + fsp_str_dbg(fsp))); fsp->update_write_time_triggered = true; @@ -285,28 +287,17 @@ ssize_t write_file(struct smb_request *req, } if (!fsp->modified) { - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - fsp->modified = True; - status = create_synthetic_smb_fname_split(talloc_tos(), - fsp->fsp_name, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; - } - - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == 0) { + if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == 0) { int dosmode; trigger_write_time_update(fsp); - dosmode = dos_mode(fsp->conn, smb_fname); + dosmode = dos_mode(fsp->conn, fsp->fsp_name); if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) { - file_set_dosmode(fsp->conn, smb_fname, - dosmode | aARCH, NULL, false); + file_set_dosmode(fsp->conn, fsp->fsp_name, + dosmode | aARCH, NULL, false); } /* @@ -316,11 +307,10 @@ ssize_t write_file(struct smb_request *req, if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) { setup_write_cache(fsp, - smb_fname->st.st_ex_size); + fsp->fsp_name->st.st_ex_size); wcp = fsp->wcp; } } - TALLOC_FREE(smb_fname); } #ifdef WITH_PROFILE @@ -382,8 +372,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", return total_written; } - DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n", - fsp->fsp_name, fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size)); + DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f " + "wcp->data_size=%u\n", fsp_str_dbg(fsp), fsp->fh->fd, + (double)pos, (unsigned int)n, (double)wcp->offset, + (unsigned int)wcp->data_size)); fsp->fh->pos = pos + n; @@ -828,7 +820,8 @@ void delete_write_cache(files_struct *fsp) SAFE_FREE(wcp->data); SAFE_FREE(fsp->wcp); - DEBUG(10,("delete_write_cache: File %s deleted write cache\n", fsp->fsp_name )); + DEBUG(10,("delete_write_cache: File %s deleted write cache\n", + fsp_str_dbg(fsp))); } /**************************************************************************** @@ -871,7 +864,7 @@ static bool setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) allocated_write_caches++; DEBUG(10,("setup_write_cache: File %s allocated write cache size %lu\n", - fsp->fsp_name, (unsigned long)wcp->alloc_size )); + fsp_str_dbg(fsp), (unsigned long)wcp->alloc_size)); return True; } @@ -888,7 +881,7 @@ void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) char *msg; if (asprintf(&msg, "set_filelen_write_cache: size change " "on file %s with write cache size = %lu\n", - fsp->fsp_name, + fsp->fsp_name->base_name, (unsigned long)fsp->wcp->data_size) != -1) { smb_panic(msg); } else { @@ -970,7 +963,13 @@ NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_throug int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst) { if (fsp->fh->fd == -1) { - return vfs_stat_smb_fname(fsp->conn, fsp->fsp_name, pst); + int ret; + + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); + if (ret != -1) { + *pst = fsp->fsp_name->st; + } + return ret; } else { return SMB_VFS_FSTAT(fsp, pst); } diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 48d2288468..8bd914bf0d 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -44,6 +44,7 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, { int i; files_struct *fsp; + NTSTATUS status; /* we want to give out file handles differently on each new connection because of a common bug in MS clients where they try to @@ -100,8 +101,18 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, fsp->fnum = i + FILE_HANDLE_OFFSET; SMB_ASSERT(fsp->fnum < 65536); - string_set(&fsp->fsp_name,""); - + /* + * Create an smb_filename with "" for the base_name. There are very + * few NULL checks, so make sure it's initialized with something. to + * be safe until an audit can be done. + */ + status = create_synthetic_smb_fname(fsp, "", NULL, NULL, + &fsp->fsp_name); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(fsp); + TALLOC_FREE(fsp->fh); + } + DLIST_ADD(Files, fsp); DEBUG(5,("allocated file structure %d, fnum = %d (%d used)\n", @@ -241,8 +252,9 @@ void file_dump_open_table(void) files_struct *fsp; for (fsp=Files;fsp;fsp=fsp->next,count++) { - DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, fileid=%s\n", - count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->fh->gen_id, + DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, " + "fileid=%s\n", count, fsp->fnum, fsp_str_dbg(fsp), + fsp->fh->fd, (unsigned long)fsp->fh->gen_id, file_id_string_tos(&fsp->file_id))); } } @@ -288,8 +300,10 @@ files_struct *file_find_dif(struct file_id id, unsigned long gen_id) if ((fsp->fh->fd == -1) && (fsp->oplock_type != NO_OPLOCK) && (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) { - DEBUG(0,("file_find_dif: file %s file_id = %s, gen = %u \ -oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name, + DEBUG(0,("file_find_dif: file %s file_id = " + "%s, gen = %u oplock_type = %u is a " + "stat open with oplock type !\n", + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), (unsigned int)fsp->fh->gen_id, (unsigned int)fsp->oplock_type )); @@ -390,10 +404,11 @@ bool file_find_subpath(files_struct *dir_fsp) { files_struct *fsp; size_t dlen; - char *d_fullname = talloc_asprintf(talloc_tos(), - "%s/%s", - dir_fsp->conn->connectpath, - dir_fsp->fsp_name); + char *d_fullname; + + d_fullname = talloc_asprintf(talloc_tos(), "%s/%s", + dir_fsp->conn->connectpath, + dir_fsp->fsp_name->base_name); if (!d_fullname) { return false; @@ -411,7 +426,7 @@ bool file_find_subpath(files_struct *dir_fsp) d1_fullname = talloc_asprintf(talloc_tos(), "%s/%s", fsp->conn->connectpath, - fsp->fsp_name); + fsp->fsp_name->base_name); if (strnequal(d_fullname, d1_fullname, dlen)) { TALLOC_FREE(d_fullname); @@ -449,8 +464,6 @@ void file_free(struct smb_request *req, files_struct *fsp) { DLIST_REMOVE(Files, fsp); - string_free(&fsp->fsp_name); - TALLOC_FREE(fsp->fake_file_handle); if (fsp->fh->ref_count == 1) { @@ -500,6 +513,7 @@ void file_free(struct smb_request *req, files_struct *fsp) information */ ZERO_STRUCTP(fsp); + /* fsp->fsp_name is a talloc child and is free'd automatically. */ TALLOC_FREE(fsp); } @@ -546,7 +560,7 @@ files_struct *file_fsp(struct smb_request *req, uint16 fid) Duplicate the file handle part for a DOS or FCB open. ****************************************************************************/ -void dup_file_fsp(struct smb_request *req, files_struct *from, +NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, uint32 access_mask, uint32 share_access, uint32 create_options, files_struct *to) { @@ -575,5 +589,34 @@ void dup_file_fsp(struct smb_request *req, files_struct *from, to->modified = from->modified; to->is_directory = from->is_directory; to->aio_write_behind = from->aio_write_behind; - string_set(&to->fsp_name,from->fsp_name); + return fsp_set_smb_fname(to, from->fsp_name); +} + +/** + * Return a debug string using the debug_ctx(). This can only be called from + * DEBUG() macros due to the debut_ctx(). + */ +const char *fsp_str_dbg(const struct files_struct *fsp) +{ + return smb_fname_str_dbg(fsp->fsp_name); +} + +/** + * The only way that the fsp->fsp_name field should ever be set. + */ +NTSTATUS fsp_set_smb_fname(struct files_struct *fsp, + const struct smb_filename *smb_fname_in) +{ + NTSTATUS status; + struct smb_filename *smb_fname_new; + + status = copy_smb_filename(fsp, smb_fname_in, &smb_fname_new); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + TALLOC_FREE(fsp->fsp_name); + fsp->fsp_name = smb_fname_new; + + return NT_STATUS_OK; } diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 1067dab074..96a411dd70 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -454,7 +454,7 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid, } DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n", - subcommand, fsp->fsp_name, pnum)); + subcommand, fsp_str_dbg(fsp), pnum)); DEBUG(10, ("api_fd_reply: p:%p max_trans_reply: %d\n", fsp, mdrcnt)); diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index ded888c021..8f37923865 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -182,7 +182,7 @@ void change_notify_reply(connection_struct *conn, static void notify_callback(void *private_data, const struct notify_event *e) { files_struct *fsp = (files_struct *)private_data; - DEBUG(10, ("notify_callback called for %s\n", fsp->fsp_name)); + DEBUG(10, ("notify_callback called for %s\n", fsp_str_dbg(fsp))); notify_fsp(fsp, e->action, e->path); } @@ -200,8 +200,9 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter, return NT_STATUS_NO_MEMORY; } + /* Do notify operations on the base_name. */ if (asprintf(&fullpath, "%s/%s", fsp->conn->connectpath, - fsp->fsp_name) == -1) { + fsp->fsp_name->base_name) == -1) { DEBUG(0, ("asprintf failed\n")); TALLOC_FREE(fsp->notify); return NT_STATUS_NO_MEMORY; @@ -236,7 +237,7 @@ NTSTATUS change_notify_add_request(struct smb_request *req, struct smbd_server_connection *sconn = smbd_server_conn; DEBUG(10, ("change_notify_add_request: Adding request for %s: " - "max_param = %d\n", fsp->fsp_name, (int)max_param)); + "max_param = %d\n", fsp_str_dbg(fsp), (int)max_param)); if (!(request = talloc(NULL, struct notify_change_request)) || !(map = talloc(request, struct notify_mid_map))) { diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index b65af26eca..ff76b7a21f 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -794,7 +794,7 @@ static NTSTATUS set_sd(files_struct *fsp, uint8 *data, uint32 sd_len, security_acl_map_generic(psd->sacl, &file_generic_mapping); if (DEBUGLEVEL >= 10) { - DEBUG(10,("set_sd for file %s\n", fsp->fsp_name )); + DEBUG(10,("set_sd for file %s\n", fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, psd); } @@ -1523,7 +1523,7 @@ static void call_nt_transact_notify_change(connection_struct *conn, DEBUG(3,("call_nt_transact_notify_change: notify change " "called on %s, filter = %s, recursive = %d\n", - fsp->fsp_name, filter_string, recursive)); + fsp_str_dbg(fsp), filter_string, recursive)); TALLOC_FREE(filter_string); } @@ -1626,7 +1626,7 @@ static void call_nt_transact_rename(connection_struct *conn, send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0); DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n", - fsp->fsp_name, new_name)); + fsp_str_dbg(fsp), new_name)); return; } @@ -1684,8 +1684,9 @@ static void call_nt_transact_query_security_desc(connection_struct *conn, security_info_wanted = IVAL(params,4); - DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name, - (unsigned int)security_info_wanted )); + DEBUG(3,("call_nt_transact_query_security_desc: file = %s, " + "info_wanted = 0x%x\n", fsp_str_dbg(fsp), + (unsigned int)security_info_wanted)); params = nttrans_realloc(ppparams, 4); if(params == NULL) { @@ -1722,7 +1723,8 @@ static void call_nt_transact_query_security_desc(connection_struct *conn, DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size)); if (DEBUGLEVEL >= 10) { - DEBUG(10,("call_nt_transact_query_security_desc for file %s\n", fsp->fsp_name)); + DEBUG(10,("call_nt_transact_query_security_desc for file %s\n", + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, psd); } @@ -1796,8 +1798,8 @@ static void call_nt_transact_set_security_desc(connection_struct *conn, security_info_sent = IVAL(params,4); - DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name, - (unsigned int)security_info_sent )); + DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", + fsp_str_dbg(fsp), (unsigned int)security_info_sent)); if (data_count == 0) { reply_doserror(req, ERRDOS, ERRnoaccess); @@ -2021,7 +2023,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, cur_pdata+=12; DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n", - shadow_data->num_volumes,fsp->fsp_name)); + shadow_data->num_volumes, fsp_str_dbg(fsp))); if (labels && shadow_data->labels) { for (i=0;inum_volumes;i++) { srvstr_push(pdata, req->flags2, diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 404461fb5e..33763d202d 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -219,13 +219,13 @@ void change_file_owner_to_parent(connection_struct *conn, if (ret == -1) { DEBUG(0,("change_file_owner_to_parent: failed to fchown " "file %s to parent directory uid %u. Error " - "was %s\n", fsp->fsp_name, + "was %s\n", fsp_str_dbg(fsp), (unsigned int)smb_fname_parent->st.st_ex_uid, strerror(errno) )); } DEBUG(10,("change_file_owner_to_parent: changed new file %s to " - "parent directory uid %u.\n", fsp->fsp_name, + "parent directory uid %u.\n", fsp_str_dbg(fsp), (unsigned int)smb_fname_parent->st.st_ex_uid)); TALLOC_FREE(smb_fname_parent); @@ -350,7 +350,6 @@ static NTSTATUS open_file(files_struct *fsp, uint32 access_mask, /* client requested access mask. */ uint32 open_access_mask) /* what we're actually using in the open. */ { - char *path = NULL; NTSTATUS status = NT_STATUS_OK; int accmode = (flags & O_ACCMODE); int local_flags = flags; @@ -435,7 +434,7 @@ static NTSTATUS open_file(files_struct *fsp, * wildcard characters are allowed in stream names * only test the basefilename */ - wild = fsp->base_fsp->fsp_name; + wild = fsp->base_fsp->fsp_name->base_name; } else { wild = smb_fname->base_name; } @@ -615,16 +614,13 @@ static NTSTATUS open_file(files_struct *fsp, conn->case_sensitive)) { fsp->aio_write_behind = True; } - - status = get_full_smb_filename(talloc_tos(), smb_fname, - &path); + status = fsp_set_smb_fname(fsp, smb_fname); if (!NT_STATUS_IS_OK(status)) { + fd_close(fsp); + errno = map_errno_from_nt_status(status); return status; } - string_set(&fsp->fsp_name, path); - TALLOC_FREE(path); - fsp->wcp = NULL; /* Write cache pointer. */ DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", @@ -796,7 +792,8 @@ static void validate_my_share_entries(int num, str = talloc_asprintf(talloc_tos(), "validate_my_share_entries: " "file %s, oplock_type = 0x%x, op_type = 0x%x\n", - fsp->fsp_name, (unsigned int)fsp->oplock_type, + fsp->fsp_name->base_name, + (unsigned int)fsp->oplock_type, (unsigned int)share_entry->op_type ); smb_panic(str); } @@ -1030,7 +1027,7 @@ static bool delay_for_oplocks(struct share_mode_lock *lck, } DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n", - fsp->oplock_type, fsp->fsp_name)); + fsp->oplock_type, fsp_str_dbg(fsp))); /* No delay. */ return false; @@ -1153,13 +1150,6 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, uint32 create_options) { files_struct *fsp; - char *fname = NULL; - NTSTATUS status; - - status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } DEBUG(5,("fcb_or_dos_open: attempting old open semantics for " "file %s.\n", smb_fname_str_dbg(smb_fname))); @@ -1169,7 +1159,7 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, " "vuid = %u, file_pid = %u, private_options = 0x%x " - "access_mask = 0x%x\n", fsp->fsp_name, + "access_mask = 0x%x\n", fsp_str_dbg(fsp), fsp->fh->fd, (unsigned int)fsp->vuid, (unsigned int)fsp->file_pid, (unsigned int)fsp->fh->private_options, @@ -1181,7 +1171,9 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) && (fsp->access_mask & FILE_WRITE_DATA) && - strequal(fsp->fsp_name, fname)) { + strequal(fsp->fsp_name->base_name, smb_fname->base_name) && + strequal(fsp->fsp_name->stream_name, + smb_fname->stream_name)) { DEBUG(10,("fcb_or_dos_open: file match\n")); break; } @@ -1199,10 +1191,8 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, } /* We need to duplicate this fsp. */ - dup_file_fsp(req, fsp, access_mask, share_access, - create_options, fsp_to_dup_into); - - return NT_STATUS_OK; + return dup_file_fsp(req, fsp, access_mask, share_access, + create_options, fsp_to_dup_into); } /**************************************************************************** @@ -2612,8 +2602,10 @@ static NTSTATUS open_directory(connection_struct *conn, fsp->sent_oplock_break = NO_BREAK_SENT; fsp->is_directory = True; fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False; - - string_set(&fsp->fsp_name, smb_dname->base_name); + status = fsp_set_smb_fname(fsp, smb_dname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } mtimespec = smb_dname->st.st_ex_mtime; @@ -2731,6 +2723,11 @@ void msg_file_was_renamed(struct messaging_context *msg, bn_len = strlen(base_name); stream_name = sharepath + sp_len + 1 + bn_len + 1; + /* stream_name must always be NULL if there is no stream. */ + if (stream_name[0] == '\0') { + stream_name = NULL; + } + status = create_synthetic_smb_fname(talloc_tos(), base_name, stream_name, NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -2744,18 +2741,14 @@ void msg_file_was_renamed(struct messaging_context *msg, for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) { if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) { - char *newname = NULL; DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n", - fsp->fnum, fsp->fsp_name, + fsp->fnum, fsp_str_dbg(fsp), smb_fname_str_dbg(smb_fname))); - status = get_full_smb_filename(talloc_tos(), - smb_fname, &newname); + status = fsp_set_smb_fname(fsp, smb_fname); if (!NT_STATUS_IS_OK(status)) { goto out; } - string_set(&fsp->fsp_name, newname); - TALLOC_FREE(newname); } else { /* TODO. JRA. */ /* Now we have the complete path we can work out if this is @@ -2766,7 +2759,7 @@ void msg_file_was_renamed(struct messaging_context *msg, fsp->conn->connectpath, sharepath, fsp->fnum, - fsp->fsp_name, + fsp_str_dbg(fsp), smb_fname_str_dbg(smb_fname))); } } @@ -2927,7 +2920,7 @@ NTSTATUS open_streams_for_delete(connection_struct *conn, } DEBUG(10, ("Closing stream # %d, %s\n", i, - streams[i]->fsp_name)); + fsp_str_dbg(streams[i]))); close_file(NULL, streams[i], NORMAL_CLOSE); } @@ -3327,6 +3320,11 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, dir_fsp = file_fsp(req, root_dir_fid); + if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) { + status = NT_STATUS_INVALID_HANDLE; + goto out; + } + if (dir_fsp == NULL) { status = NT_STATUS_INVALID_HANDLE; goto out; @@ -3355,7 +3353,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, goto out; } - if (ISDOT(dir_fsp->fsp_name)) { + if (ISDOT(dir_fsp->fsp_name->base_name)) { /* * We're at the toplevel dir, the final file name * must not contain ./, as this is filtered out @@ -3368,7 +3366,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, goto out; } } else { - size_t dir_name_len = strlen(dir_fsp->fsp_name); + size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name); /* * Copy in the base directory name. @@ -3380,7 +3378,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, status = NT_STATUS_NO_MEMORY; goto out; } - memcpy(parent_fname, dir_fsp->fsp_name, + memcpy(parent_fname, dir_fsp->fsp_name->base_name, dir_name_len+1); /* diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index e9b2a6cf95..dd8d5372fb 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -81,7 +81,7 @@ bool set_file_oplock(files_struct *fsp, int oplock_type) DEBUG(5,("set_file_oplock: granted oplock on file %s, %s/%lu, " "tv_sec = %x, tv_usec = %x\n", - fsp->fsp_name, file_id_string_tos(&fsp->file_id), + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, (int)fsp->open_time.tv_sec, (int)fsp->open_time.tv_usec )); @@ -158,14 +158,15 @@ bool remove_oplock(files_struct *fsp) NULL); if (lck == NULL) { DEBUG(0,("remove_oplock: failed to lock share entry for " - "file %s\n", fsp->fsp_name )); + "file %s\n", fsp_str_dbg(fsp))); return False; } ret = remove_share_oplock(lck, fsp); if (!ret) { DEBUG(0,("remove_oplock: failed to remove share oplock for " "file %s fnum %d, %s\n", - fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id))); + fsp_str_dbg(fsp), fsp->fnum, + file_id_string_tos(&fsp->file_id))); } release_file_oplock(fsp); TALLOC_FREE(lck); @@ -184,14 +185,15 @@ bool downgrade_oplock(files_struct *fsp) NULL); if (lck == NULL) { DEBUG(0,("downgrade_oplock: failed to lock share entry for " - "file %s\n", fsp->fsp_name )); + "file %s\n", fsp_str_dbg(fsp))); return False; } ret = downgrade_share_oplock(lck, fsp); if (!ret) { DEBUG(0,("downgrade_oplock: failed to downgrade share oplock " "for file %s fnum %d, file_id %s\n", - fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id))); + fsp_str_dbg(fsp), fsp->fnum, + file_id_string_tos(&fsp->file_id))); } downgrade_file_oplock(fsp); @@ -294,7 +296,8 @@ static files_struct *initial_break_processing(struct file_id id, unsigned long f if(fsp->oplock_type == NO_OPLOCK) { if( DEBUGLVL( 3 ) ) { - dbgtext( "initial_break_processing: file %s ", fsp->fsp_name ); + dbgtext( "initial_break_processing: file %s ", + fsp_str_dbg(fsp)); dbgtext( "(file_id = %s gen_id = %lu) has no oplock.\n", file_id_string_tos(&id), fsp->fh->gen_id ); dbgtext( "Allowing break to succeed regardless.\n" ); @@ -314,7 +317,8 @@ static void oplock_timeout_handler(struct event_context *ctx, /* Remove the timed event handler. */ TALLOC_FREE(fsp->oplock_timeout); - DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", fsp->fsp_name)); + DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", + fsp_str_dbg(fsp))); global_client_failed_oplock_break = True; remove_oplock(fsp); reply_to_oplock_break_requests(fsp); @@ -375,7 +379,7 @@ void break_level2_to_none_async(files_struct *fsp) DEBUG(10,("process_oplock_async_level2_break_message: sending break " "to none message for fid %d, file %s\n", fsp->fnum, - fsp->fsp_name)); + fsp_str_dbg(fsp))); /* Now send a break to none message to our client. */ break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE); @@ -506,7 +510,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { DEBUG(3, ("Already downgraded oplock on %s: %s\n", file_id_string_tos(&fsp->file_id), - fsp->fsp_name)); + fsp_str_dbg(fsp))); /* We just send the same message back. */ messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE, (uint8 *)data->data, @@ -740,7 +744,7 @@ static void contend_level2_oplocks_begin_default(files_struct *fsp, NULL); if (lck == NULL) { DEBUG(0,("release_level_2_oplocks_on_change: failed to lock " - "share mode entry for file %s.\n", fsp->fsp_name )); + "share mode entry for file %s.\n", fsp_str_dbg(fsp))); return; } diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c index 89b8e0f7b5..dd32177988 100644 --- a/source3/smbd/oplock_irix.c +++ b/source3/smbd/oplock_irix.c @@ -212,7 +212,8 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx, DEBUG(0,("irix_set_kernel_oplock: Unable to get " "kernel oplock on file %s, file_id %s " "gen_id = %ul. Error was %s\n", - fsp->fsp_name, file_id_string_tos(&fsp->file_id), + fsp_str_dbg(fsp), + file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, strerror(errno) )); } else { @@ -220,7 +221,7 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx, "file %s, fd = %d, file_id = %s, " "gen_id = %ul. Another process had the file " "open.\n", - fsp->fsp_name, fsp->fh->fd, + fsp_str_dbg(fsp), fsp->fh->fd, file_id_string_tos(&fsp->file_id), fsp->fh->gen_id )); } @@ -229,7 +230,7 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx, DEBUG(10,("irix_set_kernel_oplock: got kernel oplock on file %s, file_id = %s " "gen_id = %ul\n", - fsp->fsp_name, file_id_string_tos(&fsp->file_id), + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), fsp->fh->gen_id)); return True; @@ -250,7 +251,8 @@ static void irix_release_kernel_oplock(struct kernel_oplocks *_ctx, int state = sys_fcntl_long(fsp->fh->fd, F_OPLKACK, -1); dbgtext("irix_release_kernel_oplock: file %s, file_id = %s" "gen_id = %ul, has kernel oplock state " - "of %x.\n", fsp->fsp_name, file_id_string_tos(&fsp->file_id), + "of %x.\n", fsp_str_dbg(fsp), + file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, state ); } @@ -263,7 +265,8 @@ static void irix_release_kernel_oplock(struct kernel_oplocks *_ctx, "removing kernel oplock on file " ); dbgtext("%s, file_id = %s gen_id = %ul. " "Error was %s\n", - fsp->fsp_name, file_id_string_tos(&fsp->file_id), + fsp_str_dbg(fsp), + file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, strerror(errno) ); } diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c index 273fbfdc01..b4a5495e4b 100644 --- a/source3/smbd/oplock_linux.c +++ b/source3/smbd/oplock_linux.c @@ -111,7 +111,7 @@ static bool linux_set_kernel_oplock(struct kernel_oplocks *ctx, if ( SMB_VFS_LINUX_SETLEASE(fsp, F_WRLCK) == -1) { DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, " "fd = %d, file_id = %s. (%s)\n", - fsp->fsp_name, fsp->fh->fd, + fsp_str_dbg(fsp), fsp->fh->fd, file_id_string_tos(&fsp->file_id), strerror(errno))); return False; @@ -119,7 +119,7 @@ static bool linux_set_kernel_oplock(struct kernel_oplocks *ctx, DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, " "file_id = %s gen_id = %lu\n", - fsp->fsp_name, file_id_string_tos(&fsp->file_id), + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), fsp->fh->gen_id)); return True; @@ -140,7 +140,8 @@ static void linux_release_kernel_oplock(struct kernel_oplocks *ctx, int state = fcntl(fsp->fh->fd, F_GETLEASE, 0); dbgtext("linux_release_kernel_oplock: file %s, file_id = %s " "gen_id = %lu has kernel oplock state " - "of %x.\n", fsp->fsp_name, file_id_string_tos(&fsp->file_id), + "of %x.\n", fsp_str_dbg(fsp), + file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, state ); } @@ -152,7 +153,7 @@ static void linux_release_kernel_oplock(struct kernel_oplocks *ctx, dbgtext("linux_release_kernel_oplock: Error when " "removing kernel oplock on file " ); dbgtext("%s, file_id = %s, gen_id = %lu. " - "Error was %s\n", fsp->fsp_name, + "Error was %s\n", fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, strerror(errno) ); } diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c index 497cfc7b54..a73100abdf 100644 --- a/source3/smbd/oplock_onefs.c +++ b/source3/smbd/oplock_onefs.c @@ -74,7 +74,8 @@ const char *onefs_cb_record_str_dbg(const struct onefs_callback_record *r) switch (r->state) { case ONEFS_OPEN_FILE: result = talloc_asprintf(dbg_ctx(), "cb record %llu for file " - "%s", r->id, r->data.fsp->fsp_name); + "%s", r->id, + fsp_str_dbg(r->data.fsp)); case ONEFS_WAITING_FOR_OPLOCK: result = talloc_asprintf(dbg_ctx(), "cb record %llu for " "pending mid %d", r->id, @@ -299,7 +300,7 @@ static void oplock_break_to_none_handler(uint64_t id) } DEBUG(10, ("oplock_break_to_none_handler called for file %s\n", - cb->data.fsp->fsp_name)); + cb->data.fsp_str_dbg(fsp))); init_share_mode_entry(&sme, cb, FORCE_OPLOCK_BREAK_TO_NONE); share_mode_entry_to_message(msg, &sme); @@ -336,7 +337,7 @@ static void oplock_break_to_level_two_handler(uint64_t id) } DEBUG(10, ("oplock_break_to_level_two_handler called for file %s\n", - cb->data.fsp->fsp_name)); + cb->data.fsp_str_dbg(fsp))); init_share_mode_entry(&sme, cb, LEVEL_II_OPLOCK); share_mode_entry_to_message(msg, &sme); @@ -377,7 +378,7 @@ static void oplock_revoked_handler(uint64_t id) SMB_ASSERT(fsp->oplock_timeout == NULL); DEBUG(0,("Level 1 oplock break failed for file %s. Forcefully " - "revoking oplock\n", fsp->fsp_name)); + "revoking oplock\n", fsp_str_dbg(fsp))); global_client_failed_oplock_break = True; remove_oplock(fsp); @@ -501,7 +502,7 @@ static void onefs_release_kernel_oplock(struct kernel_oplocks *_ctx, enum oplock_type oplock = onefs_samba_oplock_to_oplock(oplock_type); DEBUG(10, ("onefs_release_kernel_oplock: Releasing %s to type %s\n", - fsp->fsp_name, onefs_oplock_str(oplock))); + fsp_str_dbg(fsp), onefs_oplock_str(oplock))); if (fsp->fh->fd == -1) { DEBUG(1, ("no fd\n")); diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 799568d0d5..091db09987 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -37,6 +37,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, { struct connection_struct *conn = smb_req->conn; struct files_struct *fsp; + struct smb_filename *smb_fname = NULL; NTSTATUS status; status = file_new(smb_req, conn, &fsp); @@ -50,7 +51,19 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, fsp->vuid = smb_req->vuid; fsp->can_lock = false; fsp->access_mask = FILE_READ_DATA | FILE_WRITE_DATA; - string_set(&fsp->fsp_name, name); + + status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + file_free(smb_req, fsp); + return status; + } + status = fsp_set_smb_fname(fsp, smb_fname); + TALLOC_FREE(smb_fname); + if (!NT_STATUS_IS_OK(status)) { + file_free(smb_req, fsp); + return status; + } status = np_open(NULL, name, conn->client_address, conn->server_info, &fsp->fake_file_handle); @@ -179,7 +192,7 @@ void reply_pipe_write(struct smb_request *req) data = req->buf + 3; DEBUG(6, ("reply_pipe_write: %x name: %s len: %d\n", (int)fsp->fnum, - fsp->fsp_name, (int)state->numtowrite)); + fsp_str_dbg(fsp), (int)state->numtowrite)); subreq = np_write_send(state, smbd_event_context(), fsp->fake_file_handle, data, state->numtowrite); @@ -275,7 +288,7 @@ void reply_pipe_write_and_X(struct smb_request *req) == (PIPE_START_MESSAGE|PIPE_RAW_MODE)); DEBUG(6, ("reply_pipe_write_and_X: %x name: %s len: %d\n", - (int)fsp->fnum, fsp->fsp_name, (int)state->numtowrite)); + (int)fsp->fnum, fsp_str_dbg(fsp), (int)state->numtowrite)); data = (uint8_t *)smb_base(req->inbuf) + smb_doff; diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 76eee9b56a..fb2cda40ce 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -256,15 +256,16 @@ static void store_inheritance_attributes(files_struct *fsp, ret = SMB_VFS_FSETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME, pai_buf, store_size, 0); } else { - ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME, - pai_buf, store_size, 0); + ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name, + SAMBA_POSIX_INHERITANCE_EA_NAME, + pai_buf, store_size, 0); } SAFE_FREE(pai_buf); DEBUG(10,("store_inheritance_attribute: type 0x%x for file %s\n", (unsigned int)sd_type, - fsp->fsp_name)); + fsp_str_dbg(fsp))); if (ret == -1 && !no_acl_syscall_error(errno)) { DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) )); @@ -599,8 +600,10 @@ static struct pai_val *fload_inherited_info(files_struct *fsp) ret = SMB_VFS_FGETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME, pai_buf, pai_buf_size); } else { - ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME, - pai_buf, pai_buf_size); + ret = SMB_VFS_GETXATTR(fsp->conn, + fsp->fsp_name->base_name, + SAMBA_POSIX_INHERITANCE_EA_NAME, + pai_buf, pai_buf_size); } if (ret == -1) { @@ -618,7 +621,8 @@ static struct pai_val *fload_inherited_info(files_struct *fsp) } } while (ret == -1); - DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fsp->fsp_name)); + DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", + (unsigned long)ret, fsp_str_dbg(fsp))); if (ret == -1) { /* No attribute or not supported. */ @@ -637,8 +641,7 @@ static struct pai_val *fload_inherited_info(files_struct *fsp) if (paiv) { DEBUG(10,("load_inherited_info: ACL type is 0x%x for file %s\n", - (unsigned int)paiv->sd_type, - fsp->fsp_name)); + (unsigned int)paiv->sd_type, fsp_str_dbg(fsp))); } SAFE_FREE(pai_buf); @@ -1727,8 +1730,12 @@ static bool create_canon_ace_lists(files_struct *fsp, got_dir_allow = True; if ((current_ace->attr == DENY_ACE) && got_dir_allow) { - DEBUG(0,("create_canon_ace_lists: malformed ACL in inheritable ACL ! \ -Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name )); + DEBUG(0,("create_canon_ace_lists: " + "malformed ACL in " + "inheritable ACL! Deny entry " + "after Allow entry. Failing " + "to set on file %s.\n", + fsp_str_dbg(fsp))); free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); return False; @@ -1785,8 +1792,10 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name )); got_file_allow = True; if ((current_ace->attr == DENY_ACE) && got_file_allow) { - DEBUG(0,("create_canon_ace_lists: malformed ACL in file ACL ! \ -Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name )); + DEBUG(0,("create_canon_ace_lists: malformed " + "ACL in file ACL ! Deny entry after " + "Allow entry. Failing to set on file " + "%s.\n", fsp_str_dbg(fsp))); free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); return False; @@ -2169,17 +2178,8 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode) mode_t mode; if (interitable_mode) { - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - - status = create_synthetic_smb_fname_split(talloc_tos(), - fsp->fsp_name, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return 0; - } - mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE, smb_fname, - NULL); + mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE, + fsp->fsp_name, NULL); } else { mode = S_IRUSR; } @@ -2602,14 +2602,9 @@ static bool set_canon_ace_list(files_struct *fsp, SMB_ACL_TYPE_T the_acl_type = (default_ace ? SMB_ACL_TYPE_DEFAULT : SMB_ACL_TYPE_ACCESS); bool needs_mask = False; mode_t mask_perms = 0; - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - psbuf, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } + /* Use the psbuf that was passed in. */ + fsp->fsp_name->st = *psbuf; #if defined(POSIX_ACL_NEEDS_MASK) /* HP-UX always wants to have a mask (called "class" there). */ @@ -2767,7 +2762,7 @@ static bool set_canon_ace_list(files_struct *fsp, */ if(default_ace || fsp->is_directory || fsp->fh->fd == -1) { - if (SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname->base_name, + if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name->base_name, the_acl_type, the_acl) == -1) { /* * Some systems allow all the above calls and only fail with no ACL support @@ -2777,17 +2772,17 @@ static bool set_canon_ace_list(files_struct *fsp, *pacl_set_support = False; } - if (acl_group_override(conn, smb_fname)) { + if (acl_group_override(conn, fsp->fsp_name)) { int sret; DEBUG(5,("set_canon_ace_list: acl group " "control on and current user in file " "%s primary group.\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); become_root(); sret = SMB_VFS_SYS_ACL_SET_FILE(conn, - smb_fname->base_name, the_acl_type, + fsp->fsp_name->base_name, the_acl_type, the_acl); unbecome_root(); if (sret == 0) { @@ -2801,8 +2796,7 @@ static bool set_canon_ace_list(files_struct *fsp, "file %s (%s).\n", the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file", - smb_fname_str_dbg(smb_fname), - strerror(errno))); + fsp_str_dbg(fsp), strerror(errno))); goto fail; } } @@ -2816,13 +2810,13 @@ static bool set_canon_ace_list(files_struct *fsp, *pacl_set_support = False; } - if (acl_group_override(conn, smb_fname)) { + if (acl_group_override(conn, fsp->fsp_name)) { int sret; DEBUG(5,("set_canon_ace_list: acl group " "control on and current user in file " "%s primary group.\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); become_root(); sret = SMB_VFS_SYS_ACL_SET_FD(fsp, the_acl); @@ -2836,8 +2830,7 @@ static bool set_canon_ace_list(files_struct *fsp, DEBUG(2,("set_canon_ace_list: " "sys_acl_set_file failed for file %s " "(%s).\n", - smb_fname_str_dbg(smb_fname), - strerror(errno) )); + fsp_str_dbg(fsp), strerror(errno))); goto fail; } } @@ -2850,7 +2843,6 @@ static bool set_canon_ace_list(files_struct *fsp, if (the_acl != NULL) { SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl); } - TALLOC_FREE(smb_fname); return ret; } @@ -2906,8 +2898,9 @@ static bool convert_canon_ace_to_posix_perms( files_struct *fsp, canon_ace *file mode_t or_bits; if (ace_count != 3) { - DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE entries for file %s to convert to \ -posix perms.\n", fsp->fsp_name )); + DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE " + "entries for file %s to convert to posix perms.\n", + fsp_str_dbg(fsp))); return False; } @@ -2921,8 +2914,8 @@ posix perms.\n", fsp->fsp_name )); } if (!owner_ace || !group_ace || !other_ace) { - DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get standard entries for file %s.\n", - fsp->fsp_name )); + DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get " + "standard entries for file %s.\n", fsp_str_dbg(fsp))); return False; } @@ -2956,9 +2949,10 @@ posix perms.\n", fsp->fsp_name )); *posix_perms = (((*posix_perms) & and_bits)|or_bits); - DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o to perm=0%o for file %s.\n", - (int)owner_ace->perms, (int)group_ace->perms, (int)other_ace->perms, (int)*posix_perms, - fsp->fsp_name )); + DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o " + "to perm=0%o for file %s.\n", (int)owner_ace->perms, + (int)group_ace->perms, (int)other_ace->perms, + (int)*posix_perms, fsp_str_dbg(fsp))); return True; } @@ -3351,11 +3345,12 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, *ppdesc = NULL; - DEBUG(10,("posix_fget_nt_acl: called for file %s\n", fsp->fsp_name )); + DEBUG(10,("posix_fget_nt_acl: called for file %s\n", + fsp_str_dbg(fsp))); /* can it happen that fsp_name == NULL ? */ if (fsp->is_directory || fsp->fh->fd == -1) { - return posix_get_nt_acl(fsp->conn, fsp->fsp_name, + return posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name, security_info, ppdesc); } @@ -3369,8 +3364,9 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, pal = fload_inherited_info(fsp); - return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name, &sbuf, pal, - posix_acl, NULL, security_info, ppdesc); + return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name, + &sbuf, pal, posix_acl, NULL, + security_info, ppdesc); } NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, @@ -3514,7 +3510,8 @@ NTSTATUS append_parent_acl(files_struct *fsp, return NT_STATUS_NO_MEMORY; } - if (!parent_dirname(mem_ctx, fsp->fsp_name, &parent_name, NULL)) { + if (!parent_dirname(mem_ctx, fsp->fsp_name->base_name, &parent_name, + NULL)) { return NT_STATUS_NO_MEMORY; } @@ -3596,7 +3593,7 @@ NTSTATUS append_parent_acl(files_struct *fsp, "ignoring non container " "inherit flags %u on ACE with sid %s " "from parent %s\n", - fsp->fsp_name, + fsp_str_dbg(fsp), (unsigned int)se->flags, sid_string_dbg(&se->trustee), parent_name)); @@ -3609,7 +3606,7 @@ NTSTATUS append_parent_acl(files_struct *fsp, "ignoring non object " "inherit flags %u on ACE with sid %s " "from parent %s\n", - fsp->fsp_name, + fsp_str_dbg(fsp), (unsigned int)se->flags, sid_string_dbg(&se->trustee), parent_name)); @@ -3633,7 +3630,7 @@ NTSTATUS append_parent_acl(files_struct *fsp, DEBUG(10,("append_parent_acl: path %s " "ignoring ACE with protected sid %s " "from parent %s\n", - fsp->fsp_name, + fsp_str_dbg(fsp), sid_string_dbg(&se->trustee), parent_name)); continue; @@ -3671,7 +3668,7 @@ NTSTATUS append_parent_acl(files_struct *fsp, DEBUG(10,("append_parent_acl: path %s " "inheriting ACE with sid %s " "from parent %s\n", - fsp->fsp_name, + fsp_str_dbg(fsp), sid_string_dbg(&se->trustee), parent_name)); } @@ -3707,21 +3704,13 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC bool set_acl_as_root = false; bool acl_set_support = false; bool ret = false; - struct smb_filename *smb_fname = NULL; - - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } DEBUG(10,("set_nt_acl: called for file %s\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); if (!CAN_WRITE(conn)) { DEBUG(10,("set acl rejected on read-only share\n")); - status = NT_STATUS_MEDIA_WRITE_PROTECTED; - goto out; + return NT_STATUS_MEDIA_WRITE_PROTECTED; } /* @@ -3729,19 +3718,17 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC */ if(fsp->is_directory || fsp->fh->fd == -1) { - if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) { - status = map_nt_error_from_unix(errno); - goto out; + if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name) != 0) { + return map_nt_error_from_unix(errno); } } else { - if(SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { - status = map_nt_error_from_unix(errno); - goto out; + if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) { + return map_nt_error_from_unix(errno); } } /* Save the original element we check against. */ - orig_mode = smb_fname->st.st_ex_mode; + orig_mode = fsp->fsp_name->st.st_ex_mode; /* * Unpack the user/group/world id's. @@ -3749,7 +3736,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC status = unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd); if (!NT_STATUS_IS_OK(status)) { - goto out; + return status; } /* @@ -3758,24 +3745,22 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC * Noticed by Simo. */ - if (((user != (uid_t)-1) && (smb_fname->st.st_ex_uid != user)) || - (( grp != (gid_t)-1) && (smb_fname->st.st_ex_gid != grp))) { + if (((user != (uid_t)-1) && (fsp->fsp_name->st.st_ex_uid != user)) || + (( grp != (gid_t)-1) && (fsp->fsp_name->st.st_ex_gid != grp))) { DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", - smb_fname_str_dbg(smb_fname), (unsigned int)user, - (unsigned int)grp )); + fsp_str_dbg(fsp), (unsigned int)user, + (unsigned int)grp)); - if(try_chown(fsp->conn, smb_fname, user, grp) == -1) { + if(try_chown(fsp->conn, fsp->fsp_name, user, grp) == -1) { DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error " - "= %s.\n", smb_fname_str_dbg(smb_fname), + "= %s.\n", fsp_str_dbg(fsp), (unsigned int)user, (unsigned int)grp, strerror(errno))); if (errno == EPERM) { - status = NT_STATUS_INVALID_OWNER; - goto out; + return NT_STATUS_INVALID_OWNER; } - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } /* @@ -3784,25 +3769,24 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC */ if(fsp->is_directory) { - if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) { - status = map_nt_error_from_unix(errno); - goto out; + if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name) != 0) { + return map_nt_error_from_unix(errno); } } else { int sret; if(fsp->fh->fd == -1) - sret = SMB_VFS_STAT(fsp->conn, smb_fname); + sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); else - sret = SMB_VFS_FSTAT(fsp, &smb_fname->st); + sret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); if(sret != 0) return map_nt_error_from_unix(errno); } /* Save the original element we check against. */ - orig_mode = smb_fname->st.st_ex_mode; + orig_mode = fsp->fsp_name->st.st_ex_mode; /* If we successfully chowned, we know we must * be able to set the acl, so do it as root. @@ -3810,24 +3794,22 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC set_acl_as_root = true; } - create_file_sids(&smb_fname->st, &file_owner_sid, &file_grp_sid); + create_file_sids(&fsp->fsp_name->st, &file_owner_sid, &file_grp_sid); - acl_perms = unpack_canon_ace(fsp, &smb_fname->st, &file_owner_sid, + acl_perms = unpack_canon_ace(fsp, &fsp->fsp_name->st, &file_owner_sid, &file_grp_sid, &file_ace_list, &dir_ace_list, security_info_sent, psd); /* Ignore W2K traverse DACL set. */ if (!file_ace_list && !dir_ace_list) { - status = NT_STATUS_OK; - goto out; + return NT_STATUS_OK; } if (!acl_perms) { DEBUG(3,("set_nt_acl: cannot set permissions\n")); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = NT_STATUS_ACCESS_DENIED; - goto out; + return NT_STATUS_ACCESS_DENIED; } /* @@ -3837,8 +3819,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) { free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = NT_STATUS_OK; - goto out; + return NT_STATUS_OK; } /* @@ -3851,18 +3832,17 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC become_root(); } ret = set_canon_ace_list(fsp, file_ace_list, false, - &smb_fname->st, &acl_set_support); + &fsp->fsp_name->st, &acl_set_support); if (set_acl_as_root) { unbecome_root(); } if (acl_set_support && ret == false) { DEBUG(3,("set_nt_acl: failed to set file acl on file " - "%s (%s).\n", smb_fname_str_dbg(smb_fname), + "%s (%s).\n", fsp_str_dbg(fsp), strerror(errno))); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } } @@ -3872,7 +3852,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC become_root(); } ret = set_canon_ace_list(fsp, dir_ace_list, true, - &smb_fname->st, + &fsp->fsp_name->st, &acl_set_support); if (set_acl_as_root) { unbecome_root(); @@ -3880,12 +3860,10 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC if (ret == false) { DEBUG(3,("set_nt_acl: failed to set default " "acl on directory %s (%s).\n", - smb_fname_str_dbg(smb_fname), - strerror(errno) )); + fsp_str_dbg(fsp), strerror(errno))); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } } else { int sret = -1; @@ -3898,23 +3876,23 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC become_root(); } sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, - smb_fname->base_name); + fsp->fsp_name->base_name); if (set_acl_as_root) { unbecome_root(); } if (sret == -1) { - if (acl_group_override(conn, smb_fname)) { + if (acl_group_override(conn, fsp->fsp_name)) { DEBUG(5,("set_nt_acl: acl group " "control on and current user " "in file %s primary group. " "Override delete_def_acl\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); become_root(); sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE( conn, - smb_fname->base_name); + fsp->fsp_name->base_name); unbecome_root(); } @@ -3922,8 +3900,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno))); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } } } @@ -3954,52 +3931,48 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC free_canon_ace_list(dir_ace_list); DEBUG(3,("set_nt_acl: failed to convert file acl to " "posix permissions for file %s.\n", - smb_fname_str_dbg(smb_fname))); - status = NT_STATUS_ACCESS_DENIED; - goto out; + fsp_str_dbg(fsp))); + return NT_STATUS_ACCESS_DENIED; } if (orig_mode != posix_perms) { int sret = -1; DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n", - smb_fname_str_dbg(smb_fname), - (unsigned int)posix_perms)); + fsp_str_dbg(fsp), (unsigned int)posix_perms)); if (set_acl_as_root) { become_root(); } - sret = SMB_VFS_CHMOD(conn, smb_fname->base_name, + sret = SMB_VFS_CHMOD(conn, fsp->fsp_name->base_name, posix_perms); if (set_acl_as_root) { unbecome_root(); } if(sret == -1) { - if (acl_group_override(conn, smb_fname)) { + if (acl_group_override(conn, fsp->fsp_name)) { DEBUG(5,("set_nt_acl: acl group " "control on and current user " "in file %s primary group. " "Override chmod\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); become_root(); - sret = - SMB_VFS_CHMOD(conn, - smb_fname->base_name, - posix_perms); + sret = SMB_VFS_CHMOD(conn, + fsp->fsp_name->base_name, + posix_perms); unbecome_root(); } if (sret == -1) { DEBUG(3,("set_nt_acl: chmod %s, 0%o " "failed. Error = %s.\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), (unsigned int)posix_perms, strerror(errno))); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } } } @@ -4008,10 +3981,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = NT_STATUS_OK; - out: - TALLOC_FREE(smb_fname); - return status; + return NT_STATUS_OK; } /**************************************************************************** @@ -4614,6 +4584,7 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname) connection_struct *conn; files_struct finfo; struct fd_handle fh; + NTSTATUS status; conn = TALLOC_ZERO_P(ctx, connection_struct); if (conn == NULL) { @@ -4644,16 +4615,24 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname) finfo.conn = conn; finfo.fh = &fh; finfo.fh->fd = -1; - finfo.fsp_name = CONST_DISCARD(char *,fname); + + status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL, + &finfo.fsp_name); + if (!NT_STATUS_IS_OK(status)) { + conn_free_internal( conn ); + return NULL; + } if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, DACL_SECURITY_INFORMATION, &psd))) { DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n")); + TALLOC_FREE(finfo.fsp_name); conn_free_internal( conn ); return NULL; } ret_sd = dup_sec_desc( ctx, psd ); + TALLOC_FREE(finfo.fsp_name); conn_free_internal( conn ); return ret_sd; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index a6e35c7342..46fdd4adde 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1812,7 +1812,8 @@ void reply_open(struct smb_request *req) mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime); if (fattr & aDIR) { - DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name)); + DEBUG(3,("attempt to open a directory %s\n", + fsp_str_dbg(fsp))); close_file(req, fsp, ERROR_CLOSE); reply_doserror(req, ERRDOS,ERRnoaccess); goto out; @@ -2313,9 +2314,9 @@ void reply_ctemp(struct smb_request *req) SSVAL(req->outbuf,smb_vwv0,fsp->fnum); /* the returned filename is relative to the directory */ - s = strrchr_m(fsp->fsp_name, '/'); + s = strrchr_m(fsp->fsp_name->base_name, '/'); if (!s) { - s = fsp->fsp_name; + s = fsp->fsp_name->base_name; } else { s++; } @@ -2341,8 +2342,8 @@ void reply_ctemp(struct smb_request *req) CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED); } - DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) ); - DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name, + DEBUG(2, ("reply_ctemp: created temp file %s\n", fsp_str_dbg(fsp))); + DEBUG(3, ("reply_ctemp %s fd=%d umode=0%o\n", fsp_str_dbg(fsp), fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode)); out: TALLOC_FREE(smb_fname); @@ -2357,22 +2358,13 @@ void reply_ctemp(struct smb_request *req) static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp, uint16 dirtype, SMB_STRUCT_STAT *pst) { - struct smb_filename *smb_fname = NULL; - NTSTATUS status; uint32 fmode; if (!CAN_WRITE(conn)) { return NT_STATUS_MEDIA_WRITE_PROTECTED; } - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - pst, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - fmode = dos_mode(conn, smb_fname); - TALLOC_FREE(smb_fname); + fmode = dos_mode(conn, fsp->fsp_name); if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) { return NT_STATUS_NO_SUCH_FILE; } @@ -2866,7 +2858,7 @@ static void sendfile_short_send(files_struct *fsp, if (nread < headersize) { DEBUG(0,("sendfile_short_send: sendfile failed to send " "header for file %s (%s). Terminating\n", - fsp->fsp_name, strerror(errno) )); + fsp_str_dbg(fsp), strerror(errno))); exit_server_cleanly("sendfile_short_send failed"); } @@ -2880,7 +2872,7 @@ static void sendfile_short_send(files_struct *fsp, } DEBUG(0,("sendfile_short_send: filling truncated file %s " - "with zeros !\n", fsp->fsp_name)); + "with zeros !\n", fsp_str_dbg(fsp))); while (nread < smb_maxcnt) { /* @@ -2975,15 +2967,19 @@ static void send_file_readbraw(connection_struct *conn, DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n")); if (fake_sendfile(fsp, startpos, nread) == -1) { - DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readbraw: " + "fake_sendfile failed for " + "file %s (%s).\n", + fsp_str_dbg(fsp), + strerror(errno))); exit_server_cleanly("send_file_readbraw fake_sendfile failed"); } return; } - DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readbraw: sendfile failed for " + "file %s (%s). Terminating\n", + fsp_str_dbg(fsp), strerror(errno))); exit_server_cleanly("send_file_readbraw sendfile failed"); } else if (sendfile_read == 0) { /* @@ -2995,7 +2991,7 @@ static void send_file_readbraw(connection_struct *conn, */ DEBUG(3, ("send_file_readbraw: sendfile sent zero " "bytes falling back to the normal read: " - "%s\n", fsp->fsp_name)); + "%s\n", fsp_str_dbg(fsp))); goto normal_readbraw; } @@ -3507,8 +3503,11 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, nread = fake_sendfile(fsp, startpos, smb_maxcnt); if (nread == -1) { - DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readX: " + "fake_sendfile failed for " + "file %s (%s).\n", + fsp_str_dbg(fsp), + strerror(errno))); exit_server_cleanly("send_file_readX: fake_sendfile failed"); } DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n", @@ -3517,8 +3516,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, goto strict_unlock; } - DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readX: sendfile failed for file " + "%s (%s). Terminating\n", fsp_str_dbg(fsp), + strerror(errno))); exit_server_cleanly("send_file_readX sendfile failed"); } else if (nread == 0) { /* @@ -3530,7 +3530,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, */ DEBUG(3, ("send_file_readX: sendfile sent zero bytes " "falling back to the normal read: %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); goto normal_read; } @@ -3560,14 +3560,16 @@ normal_read: /* Send out the header. */ if (write_data(smbd_server_fd(), (char *)headerbuf, sizeof(headerbuf)) != sizeof(headerbuf)) { - DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readX: write_data failed for file " + "%s (%s). Terminating\n", fsp_str_dbg(fsp), + strerror(errno))); exit_server_cleanly("send_file_readX sendfile failed"); } nread = fake_sendfile(fsp, startpos, smb_maxcnt); if (nread == -1) { - DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readX: fake_sendfile failed for " + "file %s (%s).\n", fsp_str_dbg(fsp), + strerror(errno))); exit_server_cleanly("send_file_readX: fake_sendfile failed"); } goto strict_unlock; @@ -3914,7 +3916,7 @@ void reply_writebraw(struct smb_request *req) status = sync_file(conn, fsp, write_through); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); reply_nterror(req, status); error_to_writebrawerr(req); goto strict_unlock; @@ -4024,7 +4026,7 @@ void reply_writeunlock(struct smb_request *req) status = sync_file(conn, fsp, False /* write through */); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); reply_nterror(req, status); goto strict_unlock; } @@ -4158,7 +4160,7 @@ void reply_write(struct smb_request *req) status = sync_file(conn, fsp, False); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_write: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); reply_nterror(req, status); goto strict_unlock; } @@ -4441,7 +4443,7 @@ void reply_write_and_X(struct smb_request *req) status = sync_file(conn, fsp, write_through); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); reply_nterror(req, status); goto strict_unlock; } @@ -4577,7 +4579,7 @@ void reply_flush(struct smb_request *req) NTSTATUS status = sync_file(conn, fsp, True); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_flush: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); reply_nterror(req, status); END_PROFILE(SMBflush); return; @@ -4745,8 +4747,8 @@ void reply_writeclose(struct smb_request *req) */ if (numtowrite) { - DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n", - fsp->fsp_name )); + DEBUG(3,("reply_writeclose: zero length write doesn't close " + "file %s\n", fsp_str_dbg(fsp))); close_status = close_file(req, fsp, NORMAL_CLOSE); } @@ -5743,7 +5745,6 @@ static void rename_open_files(connection_struct *conn, { files_struct *fsp; bool did_rename = False; - char *fname_dst = NULL; NTSTATUS status; for(fsp = file_find_di_first(lck->id); fsp; @@ -5757,17 +5758,13 @@ static void rename_open_files(connection_struct *conn, } DEBUG(10, ("rename_open_files: renaming file fnum %d " "(file_id %s) from %s -> %s\n", fsp->fnum, - file_id_string_tos(&fsp->file_id), fsp->fsp_name, + file_id_string_tos(&fsp->file_id), fsp_str_dbg(fsp), smb_fname_str_dbg(smb_fname_dst))); - status = get_full_smb_filename(talloc_tos(), smb_fname_dst, - &fname_dst); - if (!NT_STATUS_IS_OK(status)) { - return; + status = fsp_set_smb_fname(fsp, smb_fname_dst); + if (NT_STATUS_IS_OK(status)) { + did_rename = True; } - string_set(&fsp->fsp_name, fname_dst); - did_rename = True; - TALLOC_FREE(fname_dst); } if (!did_rename) { @@ -5899,17 +5896,12 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, } /* Make a copy of the src and dst smb_fname structs */ - status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst); + status = copy_smb_filename(ctx, fsp->fsp_name, &smb_fname_src); if (!NT_STATUS_IS_OK(status)) { goto out; } - /* - * This will be replaced with copy_smb_filename() when fsp->fsp_name - * is converted to store an smb_filename struct. - */ - status = create_synthetic_smb_fname_split(ctx, fsp->fsp_name, NULL, - &smb_fname_src); + status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst); if (!NT_STATUS_IS_OK(status)) { goto out; } @@ -7273,7 +7265,7 @@ NTSTATUS smbd_do_locking(struct smb_request *req, (double)e->offset, (double)e->count, (unsigned int)e->smbpid, - fsp->fsp_name)); + fsp_str_dbg(fsp))); if (e->brltype != UNLOCK_LOCK) { /* this can only happen with SMB2 */ @@ -7312,7 +7304,7 @@ NTSTATUS smbd_do_locking(struct smb_request *req, (double)e->offset, (double)e->count, (unsigned int)e->smbpid, - fsp->fsp_name, + fsp_str_dbg(fsp), (int)timeout)); if (type & LOCKING_ANDX_CANCEL_LOCK) { @@ -7528,7 +7520,8 @@ void reply_lockingX(struct smb_request *req) DEBUG(5,("reply_lockingX: Error : oplock break from " "client for fnum = %d (oplock=%d) and no " "oplock granted on this file (%s).\n", - fsp->fnum, fsp->oplock_type, fsp->fsp_name)); + fsp->fnum, fsp->oplock_type, + fsp_str_dbg(fsp))); /* if this is a pure oplock break request then don't * send a reply */ @@ -7551,7 +7544,7 @@ void reply_lockingX(struct smb_request *req) if (!result) { DEBUG(0, ("reply_lockingX: error in removing " - "oplock on file %s\n", fsp->fsp_name)); + "oplock on file %s\n", fsp_str_dbg(fsp))); /* Hmmm. Is this panic justified? */ smb_panic("internal tdb error"); } @@ -7708,7 +7701,6 @@ void reply_readbs(struct smb_request *req) void reply_setattrE(struct smb_request *req) { connection_struct *conn = req->conn; - struct smb_filename *smb_fname = NULL; struct smb_file_time ft; files_struct *fsp; NTSTATUS status; @@ -7728,14 +7720,6 @@ void reply_setattrE(struct smb_request *req) goto out; } - /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */ - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - /* * Convert the DOS times into unix times. */ @@ -7756,7 +7740,7 @@ void reply_setattrE(struct smb_request *req) /* Ensure we have a valid stat struct for the source. */ if (fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == -1) { + if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == -1) { status = map_nt_error_from_unix(errno); reply_nterror(req, status); goto out; @@ -7765,9 +7749,9 @@ void reply_setattrE(struct smb_request *req) int ret = -1; if (fsp->posix_open) { - ret = SMB_VFS_LSTAT(conn, smb_fname); + ret = SMB_VFS_LSTAT(conn, fsp->fsp_name); } else { - ret = SMB_VFS_STAT(conn, smb_fname); + ret = SMB_VFS_STAT(conn, fsp->fsp_name); } if (ret == -1) { status = map_nt_error_from_unix(errno); @@ -7776,7 +7760,7 @@ void reply_setattrE(struct smb_request *req) } } - status = smb_set_file_time(conn, fsp, smb_fname, &ft, true); + status = smb_set_file_time(conn, fsp, fsp->fsp_name, &ft, true); if (!NT_STATUS_IS_OK(status)) { reply_doserror(req, ERRDOS, ERRnoaccess); goto out; @@ -7836,8 +7820,6 @@ void reply_getattrE(struct smb_request *req) int mode; files_struct *fsp; struct timespec create_ts; - struct smb_filename *smb_fname = NULL; - NTSTATUS status; START_PROFILE(SMBgetattrE); @@ -7862,16 +7844,9 @@ void reply_getattrE(struct smb_request *req) return; } - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - &sbuf, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - END_PROFILE(SMBgetattrE); - return; - } + fsp->fsp_name->st = sbuf; - mode = dos_mode(conn, smb_fname); - TALLOC_FREE(smb_fname); + mode = dos_mode(conn, fsp->fsp_name); /* * Convert the times into dos times. Set create diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index a46b36e2bb..acb5da7751 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -121,7 +121,7 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, status = close_file(smbreq, fsp, NORMAL_CLOSE); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("smbd_smb2_close: close_file[%s]: %s\n", - fsp->fsp_name, nt_errstr(status))); + fsp_str_dbg(fsp), nt_errstr(status))); return status; } diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index bdff1939e5..7337a345fd 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -259,7 +259,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, files_struct *result; int info; SMB_STRUCT_STAT sbuf; - struct smb_filename *smb_fname = NULL; req = tevent_req_create(mem_ctx, &state, struct smbd_smb2_create_state); @@ -316,6 +315,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, } info = FILE_WAS_CREATED; } else { + struct smb_filename *smb_fname = NULL; + /* these are ignored for SMB2 */ in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */ in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */ @@ -328,6 +329,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, NULL); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); + TALLOC_FREE(smb_fname); goto out; } @@ -348,19 +350,11 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, &info); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); + TALLOC_FREE(smb_fname); goto out; } sbuf = smb_fname->st; - } - - if (!smb_fname) { - status = create_synthetic_smb_fname_split(talloc_tos(), - result->fsp_name, - &sbuf, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - goto out; - } + TALLOC_FREE(smb_fname); } smb2req->compat_chain_fsp = smbreq->chain_fsp; @@ -379,7 +373,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, state->out_allocation_size = sbuf.st_ex_blksize * sbuf.st_ex_blocks; state->out_end_of_file = sbuf.st_ex_size; state->out_file_attributes = dos_mode(result->conn, - smb_fname); + result->fsp_name); if (state->out_file_attributes == 0) { state->out_file_attributes = FILE_ATTRIBUTE_NORMAL; } @@ -387,7 +381,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, tevent_req_done(req); out: - TALLOC_FREE(smb_fname); return tevent_req_post(req, ev); } diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c index 8ce683923b..1d3ae2eb06 100644 --- a/source3/smbd/smb2_flush.c +++ b/source3/smbd/smb2_flush.c @@ -176,7 +176,7 @@ static struct tevent_req *smbd_smb2_flush_send(TALLOC_CTX *mem_ctx, status = sync_file(smbreq->conn, fsp, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("smbd_smb2_flush: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status))); + fsp_str_dbg(fsp), nt_errstr(status))); tevent_req_nterror(req, status); return tevent_req_post(req, ev); } diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index f8c2d41e31..dda79c209f 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -244,7 +244,6 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, uint16_t file_info_level; char *data = NULL; unsigned int data_size = 0; - struct smb_filename *smb_fname = NULL; bool delete_pending = false; struct timespec write_time_ts; struct file_id fileid; @@ -271,15 +270,6 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, break; } - status = create_synthetic_smb_fname_split(state, - fsp->fsp_name, - NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - if (fsp->fake_file_handle) { /* * This is actually for the QUOTA_FAKE_FILE --metze @@ -296,34 +286,34 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, if (INFO_LEVEL_IS_UNIX(file_info_level)) { /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { + if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) { DEBUG(3,("smbd_smb2_getinfo_send: " "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname), + "(%s)\n", fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); return tevent_req_post(req, ev); } - } else if (SMB_VFS_STAT(conn, smb_fname)) { + } else if (SMB_VFS_STAT(conn, fsp->fsp_name)) { DEBUG(3,("smbd_smb2_getinfo_send: " "SMB_VFS_STAT of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); return tevent_req_post(req, ev); } - fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + fileid = vfs_file_id_from_sbuf(conn, + &fsp->fsp_name->st); get_file_infos(fileid, &delete_pending, &write_time_ts); } else { /* * Original code - this is an open file. */ - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) { DEBUG(3, ("smbd_smb2_getinfo_send: " "fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); @@ -331,14 +321,15 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, tevent_req_nterror(req, status); return tevent_req_post(req, ev); } - fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + fileid = vfs_file_id_from_sbuf(conn, + &fsp->fsp_name->st); get_file_infos(fileid, &delete_pending, &write_time_ts); } status = smbd_do_qfilepathinfo(conn, state, file_info_level, fsp, - smb_fname, + fsp->fsp_name, delete_pending, write_time_ts, ms_dfs_link, diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c index 7ab93ce574..f6d83aeeed 100644 --- a/source3/smbd/smb2_notify.c +++ b/source3/smbd/smb2_notify.c @@ -231,7 +231,7 @@ static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx, DEBUG(3,("smbd_smb2_notify_send: notify change " "called on %s, filter = %s, recursive = %d\n", - fsp->fsp_name, filter_string, recursive)); + fsp_str_dbg(fsp), filter_string, recursive)); TALLOC_FREE(filter_string); } diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c index c9f281f73e..42993511ec 100644 --- a/source3/smbd/smb2_read.c +++ b/source3/smbd/smb2_read.c @@ -281,13 +281,13 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx, if (nread < 0) { DEBUG(5,("smbd_smb2_read: read_file[%s] nread[%lld]\n", - fsp->fsp_name, (long long)nread)); + fsp_str_dbg(fsp), (long long)nread)); tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); return tevent_req_post(req, ev); } if (nread == 0 && in_length != 0) { DEBUG(5,("smbd_smb2_read: read_file[%s] end of file\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); tevent_req_nterror(req, NT_STATUS_END_OF_FILE); return tevent_req_post(req, ev); } diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c index 2974695c9f..08c4a7f5bf 100644 --- a/source3/smbd/smb2_setinfo.c +++ b/source3/smbd/smb2_setinfo.c @@ -209,7 +209,6 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, case 0x01:/* SMB2_SETINFO_FILE */ { uint16_t file_info_level; - struct smb_filename *smb_fname = NULL; char *data; int data_size; int ret_size = 0; @@ -221,15 +220,6 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, file_info_level = 0xFF00 + in_file_info_class; } - status = create_synthetic_smb_fname_split(state, - fsp->fsp_name, - NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - if (fsp->is_directory || fsp->fh->fd == -1) { /* * This is actually a SETFILEINFO on a directory @@ -238,21 +228,20 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, */ if (INFO_LEVEL_IS_UNIX(file_info_level)) { /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { + if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) { DEBUG(3,("smbd_smb2_setinfo_send: " "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname), + "(%s)\n", fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); return tevent_req_post(req, ev); } } else { - if (SMB_VFS_STAT(conn, smb_fname) != 0) { + if (SMB_VFS_STAT(conn, fsp->fsp_name) != 0) { DEBUG(3,("smbd_smb2_setinfo_send: " "fileinfo of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); @@ -270,7 +259,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, DEBUG(3,("smbd_smb2_setinfo_send: " "Cancelling print job (%s)\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); tevent_req_done(req); return tevent_req_post(req, ev); @@ -284,7 +273,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, * Original code - this is an open file. */ - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) { DEBUG(3,("smbd_smb2_setinfo_send: fstat " "of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); @@ -307,7 +296,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, status = smbd_do_setfilepathinfo(conn, smbreq, state, file_info_level, fsp, - smb_fname, + fsp->fsp_name, &data, data_size, &ret_size); diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c index 31460a01a1..f1606be623 100644 --- a/source3/smbd/smb2_write.c +++ b/source3/smbd/smb2_write.c @@ -272,14 +272,14 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx, if (((nwritten == 0) && (in_data.length != 0)) || (nwritten < 0)) { DEBUG(5,("smbd_smb2_write: write_file[%s] disk full\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); tevent_req_nterror(req, NT_STATUS_DISK_FULL); return tevent_req_post(req, ev); } DEBUG(3,("smbd_smb2_write: fnum=[%d/%s] length=%d offset=%d wrote=%d\n", - fsp->fnum, fsp->fsp_name, (int)in_data.length, + fsp->fnum, fsp_str_dbg(fsp), (int)in_data.length, (int)in_offset, (int)nwritten)); if (in_flags & 0x00000001) { @@ -289,7 +289,7 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx, status = sync_file(conn, fsp, write_through); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("smbd_smb2_write: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status))); + fsp_str_dbg(fsp), nt_errstr(status))); SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); tevent_req_nterror(req, status); return tevent_req_post(req, ev); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 122114c24f..e2efed331d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -502,8 +502,9 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, if (ea_list->ea.value.length == 0) { /* Remove the attribute. */ if (fsp && (fsp->fh->fd != -1)) { - DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n", - unix_ea_name, fsp->fsp_name)); + DEBUG(10,("set_ea: deleting ea name %s on " + "file %s by file descriptor.\n", + unix_ea_name, fsp_str_dbg(fsp))); ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name); } else { DEBUG(10,("set_ea: deleting ea name %s on file %s.\n", @@ -520,8 +521,9 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, #endif } else { if (fsp && (fsp->fh->fd != -1)) { - DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n", - unix_ea_name, fsp->fsp_name)); + DEBUG(10,("set_ea: setting ea name %s on file " + "%s by file descriptor.\n", + unix_ea_name, fsp_str_dbg(fsp))); ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name, ea_list->ea.value.data, ea_list->ea.value.length, 0); } else { @@ -1148,7 +1150,8 @@ static void call_trans2open(connection_struct *conn, SIVAL(params,20,inode); SSVAL(params,24,0); /* Padding. */ if (flags & 8) { - uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name); + uint32 ea_size = estimate_ea_size(conn, fsp, + fsp->fsp_name->base_name); SIVAL(params, 26, ea_size); } else { SIVAL(params, 26, 0); @@ -4584,7 +4587,11 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, if (S_ISDIR(sbuf.st_ex_mode)) { if (fsp && fsp->is_directory) { - def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); + def_acl = + SMB_VFS_SYS_ACL_GET_FILE( + conn, + fsp->fsp_name->base_name, + SMB_ACL_TYPE_DEFAULT); } else { def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT); } @@ -4791,14 +4798,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, return; } - fname = talloc_strdup(talloc_tos(),fsp->fsp_name); - if (!fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, - NULL, &smb_fname); + status = copy_smb_filename(talloc_tos(), fsp->fsp_name, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); return; @@ -5524,8 +5525,9 @@ static NTSTATUS smb_file_position_information(connection_struct *conn, } #endif /* LARGE_SMB_OFF_T */ - DEBUG(10,("smb_file_position_information: Set file position information for file %s to %.0f\n", - fsp->fsp_name, (double)position_information )); + DEBUG(10,("smb_file_position_information: Set file position " + "information for file %s to %.0f\n", fsp_str_dbg(fsp), + (double)position_information)); fsp->fh->position_information = position_information; return NT_STATUS_OK; } @@ -5736,8 +5738,8 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, /* Create an smb_fname to call rename_internals_fsp() with. */ status = create_synthetic_smb_fname(talloc_tos(), - fsp->base_fsp->fsp_name, - newname, NULL, &smb_fname); + fsp->base_fsp->fsp_name->base_name, newname, NULL, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { goto out; } @@ -5754,7 +5756,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, /* Create a char * to call rename_internals() with. */ base_name = talloc_asprintf(ctx, "%s%s", - fsp->base_fsp->fsp_name, + fsp->base_fsp->fsp_name->base_name, newname); if (!base_name) { status = NT_STATUS_NO_MEMORY; @@ -5811,13 +5813,15 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, } if (fsp) { - DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n", - fsp->fnum, fsp->fsp_name, base_name )); + DEBUG(10,("smb_file_rename_information: " + "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n", + fsp->fnum, fsp_str_dbg(fsp), base_name)); status = rename_internals_fsp(conn, fsp, smb_fname, 0, overwrite); } else { - DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n", - fname, base_name )); + DEBUG(10,("smb_file_rename_information: " + "SMB_FILE_RENAME_INFORMATION %s -> %s\n", + fname, base_name)); status = rename_internals(ctx, conn, req, fname, base_name, 0, overwrite, False, dest_has_wcard, FILE_WRITE_ATTRIBUTES); @@ -5872,7 +5876,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, } DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n", - fname ? fname : fsp->fsp_name, + fname ? fname : fsp_str_dbg(fsp), (unsigned int)num_file_acls, (unsigned int)num_def_acls)); @@ -5959,7 +5963,7 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn, DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u," "lock_pid = %u, count = %.0f, offset = %.0f\n", - fsp->fsp_name, + fsp_str_dbg(fsp), (unsigned int)lock_type, (unsigned int)lock_pid, (double)count, @@ -7033,7 +7037,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, NULL); if (lck == NULL) { DEBUG(0, ("smb_posix_unlink: Could not get share mode " - "lock for file %s\n", fsp->fsp_name)); + "lock for file %s\n", fsp_str_dbg(fsp))); close_file(req, fsp, NORMAL_CLOSE); return NT_STATUS_INVALID_PARAMETER; } @@ -7370,14 +7374,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } info_level = SVAL(params,2); - fname = talloc_strdup(talloc_tos(),fsp->fsp_name); - if (!fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, - NULL, &smb_fname); + status = copy_smb_filename(talloc_tos(), fsp->fsp_name, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); return; @@ -7417,7 +7415,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) { fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; - DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name )); + DEBUG(3,("call_trans2setfilepathinfo: " + "Cancelling print job (%s)\n", + fsp_str_dbg(fsp))); SSVAL(params,0,0); send_trans2_replies(conn, req, params, 2, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 2b4124bf7b..a2e3ec504c 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -487,10 +487,12 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) * Actually try and commit the space on disk.... */ - DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len )); + DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", + fsp_str_dbg(fsp), (double)len)); if (((SMB_OFF_T)len) < 0) { - DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name )); + DEBUG(0,("vfs_allocate_file_space: %s negative len " + "requested.\n", fsp_str_dbg(fsp))); errno = EINVAL; return -1; } @@ -505,8 +507,9 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) if (len < (uint64_t)st.st_ex_size) { /* Shrink - use ftruncate. */ - DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n", - fsp->fsp_name, (double)st.st_ex_size )); + DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current " + "size %.0f\n", fsp_str_dbg(fsp), + (double)st.st_ex_size)); contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK); @@ -530,13 +533,16 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) len -= st.st_ex_size; len /= 1024; /* Len is now number of 1k blocks needed. */ - space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize); + space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false, + &bsize, &dfree, &dsize); if (space_avail == (uint64_t)-1) { return -1; } - DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n", - fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)space_avail )); + DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, " + "needed blocks = %.0f, space avail = %.0f\n", + fsp_str_dbg(fsp), (double)st.st_ex_size, (double)len, + (double)space_avail)); if (len > space_avail) { errno = ENOSPC; @@ -558,14 +564,15 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len) contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN); - DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len)); + DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", + fsp_str_dbg(fsp), (double)len)); flush_write_cache(fsp, SIZECHANGE_FLUSH); if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) { set_filelen_write_cache(fsp, len); notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_ATTRIBUTES, - fsp->fsp_name); + fsp->fsp_name->base_name); } contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN); @@ -600,8 +607,10 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) return 0; } - DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n", - fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)(len - st.st_ex_size))); + DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to " + "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp), + (double)st.st_ex_size, (double)len, + (double)(len - st.st_ex_size))); contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE); @@ -625,8 +634,9 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total); if (pwrite_ret == -1) { - DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file " + "%s failed with error %s\n", + fsp_str_dbg(fsp), strerror(errno))); ret = -1; goto out; } -- cgit From c9b8a017147211d86662f40dcf835b152ab90cf4 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 18:11:32 -0700 Subject: s3: Finish plumbing the fsp->fsp_name smb_fname conversion through the modules. --- source3/modules/nfs4_acls.c | 34 +++++------ source3/modules/onefs_acl.c | 51 ++++++++-------- source3/modules/onefs_open.c | 18 +++--- source3/modules/onefs_streams.c | 10 ++- source3/modules/vfs_acl_tdb.c | 98 ++++++++++++++---------------- source3/modules/vfs_acl_xattr.c | 60 +++++++++++------- source3/modules/vfs_afsacl.c | 35 +++++++---- source3/modules/vfs_aixacl2.c | 16 ++--- source3/modules/vfs_audit.c | 4 +- source3/modules/vfs_cacheprime.c | 2 +- source3/modules/vfs_default.c | 4 +- source3/modules/vfs_extd_audit.c | 8 +-- source3/modules/vfs_full_audit.c | 93 ++++++++++++++++------------ source3/modules/vfs_gpfs.c | 33 +++++++--- source3/modules/vfs_hpuxacl.c | 20 +++--- source3/modules/vfs_hpuxacl.h | 2 +- source3/modules/vfs_shadow_copy2.c | 4 +- source3/modules/vfs_smb_traffic_analyzer.c | 18 +++--- source3/modules/vfs_streams_xattr.c | 25 +++----- source3/modules/vfs_tsmsm.c | 6 +- source3/modules/vfs_zfsacl.c | 11 ++-- source3/printing/printfsp.c | 10 ++- source3/torture/cmd_vfs.c | 13 ++-- 23 files changed, 312 insertions(+), 263 deletions(-) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 9b3c8725d5..748f17d457 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -183,7 +183,8 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf) memset(psbuf, 0, sizeof(SMB_STRUCT_STAT)); if (fsp->is_directory || fsp->fh->fd == -1) { - return smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, psbuf); + return smbacl4_GetFileOwner(fsp->conn, + fsp->fsp_name->base_name, psbuf); } if (SMB_VFS_FSTAT(fsp, psbuf) != 0) { @@ -327,7 +328,7 @@ NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, { SMB_STRUCT_STAT sbuf; - DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name)); + DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp))); if (smbacl4_fGetFileOwner(fsp, &sbuf)) { return map_nt_error_from_unix(errno); @@ -717,7 +718,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, gid_t newGID = (gid_t)-1; int saved_errno; - DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name)); + DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp))); if ((security_info_sent & (DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION)) == 0) @@ -743,26 +744,23 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, } if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) || ((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) { - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - status = create_synthetic_smb_fname_split(talloc_tos(), - fsp->fsp_name, NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - if(try_chown(fsp->conn, smb_fname, newUID, newGID)) { - DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, + if(try_chown(fsp->conn, fsp->fsp_name, newUID, + newGID)) { + DEBUG(3,("chown %s, %u, %u failed. Error = " + "%s.\n", fsp_str_dbg(fsp), + (unsigned int)newUID, + (unsigned int)newGID, strerror(errno))); - TALLOC_FREE(smb_fname); return map_nt_error_from_unix(errno); } - TALLOC_FREE(smb_fname); DEBUG(10,("chown %s, %u, %u succeeded.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); - if (smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, &sbuf)) + fsp_str_dbg(fsp), (unsigned int)newUID, + (unsigned int)newGID)); + if (smbacl4_GetFileOwner(fsp->conn, + fsp->fsp_name->base_name, + &sbuf)) return map_nt_error_from_unix(errno); /* If we successfully chowned, we know we must @@ -777,7 +775,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, return NT_STATUS_OK; } - theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, ¶ms, + theacl = smbacl4_win2nfs4(fsp->fsp_name->base_name, psd->dacl, ¶ms, sbuf.st_ex_uid, sbuf.st_ex_gid); if (!theacl) return map_nt_error_from_unix(errno); diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 5c72d10a6b..2753a9e885 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -395,8 +395,8 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd) if ((sbuf.st_ex_flags & SF_HASNTFSACL) != 0) { DEBUG(10, ("Did not canonicalize ACLs because a " - "Windows ACL set was found for file %s\n", - fsp->fsp_name)); + "Windows ACL set was found for file %s\n", + fsp_str_dbg(fsp))); return true; } break; @@ -436,7 +436,7 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd) SMB_ASSERT(new_aces_count == sd->dacl->num_aces); DEBUG(10, ("Performed canonicalization of ACLs for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); /* * At this point you would think we could just do this: @@ -535,32 +535,21 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd) if (error) { DEBUG(0, ("Failed to stat %s in simple files sharing " "compatibility mode. errno=%d\n", - fsp->fsp_name, errno)); + fsp_str_dbg(fsp), errno)); return false; } /* Only continue if this is a synthetic ACL and a directory. */ if (S_ISDIR(sbuf.st_ex_mode) && (sbuf.st_ex_flags & SF_HASNTFSACL) == 0) { - struct smb_filename *smb_fname = NULL; struct ifs_ace new_aces[6]; struct ifs_ace *old_aces; int i, num_aces_to_add = 0; mode_t file_mode = 0, dir_mode = 0; - NTSTATUS status; - - status = create_synthetic_smb_fname_split(talloc_tos(), - fsp->fsp_name, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return false; - } /* Use existing samba logic to derive the mode bits. */ - file_mode = unix_mode(fsp->conn, 0, smb_fname, NULL); - dir_mode = unix_mode(fsp->conn, aDIR, smb_fname, NULL); - - TALLOC_FREE(smb_fname); + file_mode = unix_mode(fsp->conn, 0, fsp->fsp_name, NULL); + dir_mode = unix_mode(fsp->conn, aDIR, fsp->fsp_name, NULL); /* Initialize ACEs. */ new_aces[0] = onefs_init_ace(fsp->conn, file_mode, false, USR); @@ -631,18 +620,18 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, *ppdesc = NULL; DEBUG(5, ("Getting sd for file %s. security_info=%u\n", - fsp->fsp_name, security_info)); + fsp_str_dbg(fsp), security_info)); if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE, PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) { - DEBUG(5, ("Ignoring SACL on %s.\n", fsp->fsp_name)); + DEBUG(5, ("Ignoring SACL on %s.\n", fsp_str_dbg(fsp))); security_info &= ~SACL_SECURITY_INFORMATION; } if (fsp->fh->fd == -1) { if ((fsp->fh->fd = onefs_sys_create_file(handle->conn, -1, - fsp->fsp_name, + fsp->fsp_name->base_name, 0, 0, 0, @@ -655,7 +644,7 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, 0, NULL)) == -1) { DEBUG(0, ("Error opening file %s. errno=%d (%s)\n", - fsp->fsp_name, errno, strerror(errno))); + fsp_str_dbg(fsp), errno, strerror(errno))); status = map_nt_error_from_unix(errno); goto out; } @@ -801,6 +790,7 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name, { files_struct finfo; struct fd_handle fh; + NTSTATUS status; ZERO_STRUCT(finfo); ZERO_STRUCT(fh); @@ -809,9 +799,16 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name, finfo.conn = handle->conn; finfo.fh = &fh; finfo.fh->fd = -1; - finfo.fsp_name = CONST_DISCARD(char *, name); + status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL, + &finfo.fsp_name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - return onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc); + status = onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc); + + TALLOC_FREE(finfo.fsp_name); + return status; } /** @@ -918,7 +915,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, START_PROFILE(syscall_set_sd); - DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name )); + DEBUG(5,("Setting SD on file %s.\n", fsp_str_dbg(fsp))); status = onefs_samba_sd_to_sd(sec_info_sent, psd, &sd, SNUM(handle->conn), &sec_info_effective); @@ -930,10 +927,10 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, fd = fsp->fh->fd; if (fd == -1) { - DEBUG(10,("Reopening file %s.\n", fsp->fsp_name)); + DEBUG(10,("Reopening file %s.\n", fsp_str_dbg(fsp))); if ((fd = onefs_sys_create_file(handle->conn, -1, - fsp->fsp_name, + fsp->fsp_name->base_name, 0, 0, 0, @@ -946,7 +943,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, 0, NULL)) == -1) { DEBUG(0, ("Error opening file %s. errno=%d (%s)\n", - fsp->fsp_name, errno, strerror(errno))); + fsp_str_dbg(fsp), errno, strerror(errno))); status = map_nt_error_from_unix(errno); goto out; } diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index b51d516956..31f27e907a 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -81,7 +81,6 @@ static NTSTATUS onefs_open_file(files_struct *fsp, struct security_descriptor *sd, int *granted_oplock) { - char *path = NULL; struct smb_filename *smb_fname_onefs = NULL; NTSTATUS status = NT_STATUS_OK; int accmode = (flags & O_ACCMODE); @@ -157,7 +156,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp, * wildcard characters are allowed in stream names * only test the basefilename */ - wild = fsp->base_fsp->fsp_name; + wild = fsp->base_fsp->fsp_name->base_name; } else { wild = smb_fname->base_name; } @@ -323,15 +322,13 @@ static NTSTATUS onefs_open_file(files_struct *fsp, fsp->aio_write_behind = True; } - status = get_full_smb_filename(talloc_tos(), smb_fname, - &path); + status = fsp_set_smb_fname(fsp, smb_fname); if (!NT_STATUS_IS_OK(status)) { + fd_close(fsp); + errno = map_errno_from_nt_status(status); return status; } - string_set(&fsp->fsp_name, path); - TALLOC_FREE(path); - fsp->wcp = NULL; /* Write cache pointer. */ DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", @@ -1592,7 +1589,12 @@ static NTSTATUS onefs_open_directory(connection_struct *conn, fsp->is_directory = True; fsp->posix_open = posix_open; - string_set(&fsp->fsp_name, smb_dname->base_name); + status = fsp_set_smb_fname(fsp, smb_dname); + if (!NT_STATUS_IS_OK(status)) { + fd_close(fsp); + file_free(req, fsp); + return status; + } mtimespec = smb_dname->st.st_ex_mtime; diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index ded7dc672d..66eda57a34 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -376,7 +376,7 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp, } } - onefs_adjust_stat_time(handle->conn, fsp->fsp_name, sbuf); + onefs_adjust_stat_time(handle->conn, fsp->fsp_name->base_name, sbuf); return ret; } @@ -600,7 +600,11 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp, fake_fs.conn = conn; fake_fs.fh = &fake_fh; - fake_fs.fsp_name = SMB_STRDUP(fname); + status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL, + &fake_fs.fsp_name); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } /* Iterate over the streams in the ADS directory. */ while ((dp = SMB_VFS_READDIR(conn, dirp, NULL)) != NULL) { @@ -667,7 +671,7 @@ out: close(base_fd); } - SAFE_FREE(fake_fs.fsp_name); + TALLOC_FREE(fake_fs.fsp_name); return status; } diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 64ad3e1a78..ce84bd0e3a 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -272,27 +272,24 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, { uint8 id_buf[16]; struct file_id id; - SMB_STRUCT_STAT sbuf; TDB_DATA data; struct db_context *db; struct db_record *rec; int ret = -1; DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", - (unsigned int)pblob->length, fsp->fsp_name)); + (unsigned int)pblob->length, fsp_str_dbg(fsp))); SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return NT_STATUS_INTERNAL_DB_CORRUPTION); if (fsp->fh->fd != -1) { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } else { if (fsp->posix_open) { - ret = vfs_lstat_smb_fname(handle->conn, fsp->fsp_name, - &sbuf); + ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name); } else { - ret = vfs_stat_smb_fname(handle->conn, fsp->fsp_name, - &sbuf); + ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name); } } @@ -300,7 +297,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, return map_nt_error_from_unix(errno); } - id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + id = vfs_file_id_from_sbuf(handle->conn, &fsp->fsp_name->st); /* For backwards compatibility only store the dev/inode. */ push_file_id_16((char *)id_buf, &id); @@ -381,7 +378,7 @@ static NTSTATUS get_nt_acl_tdb_internal(vfs_handle_struct *handle, NTSTATUS status; if (fsp && name == NULL) { - name = fsp->fsp_name; + name = fsp->fsp_name->base_name; } DEBUG(10, ("get_nt_acl_tdb_internal: name=%s\n", name)); @@ -450,7 +447,7 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx, *********************************************************************/ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, - const char *fname, + struct smb_filename *smb_fname, files_struct *fsp, bool container) { @@ -462,7 +459,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, size_t size; char *parent_name; - if (!parent_dirname(ctx, fname, &parent_name, NULL)) { + if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; } @@ -508,25 +505,22 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, } if (!psd || psd->dacl == NULL) { - SMB_STRUCT_STAT sbuf; int ret; TALLOC_FREE(psd); if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &smb_fname->st); } else { if (fsp && fsp->posix_open) { - ret = vfs_lstat_smb_fname(handle->conn,fname, - &sbuf); + ret = SMB_VFS_LSTAT(handle->conn, smb_fname); } else { - ret = vfs_stat_smb_fname(handle->conn,fname, - &sbuf); + ret = SMB_VFS_STAT(handle->conn, smb_fname); } } if (ret == -1) { return map_nt_error_from_unix(errno); } - psd = default_file_sd(ctx, &sbuf); + psd = default_file_sd(ctx, &smb_fname->st); if (!psd) { return NT_STATUS_NO_MEMORY; } @@ -544,7 +538,8 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp) { return store_acl_blob_fsp(handle, fsp, &blob); } else { - return store_acl_blob_pathname(handle, fname, &blob); + return store_acl_blob_pathname(handle, smb_fname->base_name, + &blob); } } @@ -561,19 +556,11 @@ static int open_acl_tdb(vfs_handle_struct *handle, uint32_t access_granted = 0; struct security_descriptor *pdesc = NULL; bool file_existed = true; - char *fname = NULL; NTSTATUS status; - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; - } - status = get_nt_acl_tdb_internal(handle, NULL, - fname, + smb_fname->base_name, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION), @@ -605,10 +592,13 @@ static int open_acl_tdb(vfs_handle_struct *handle, if (!file_existed && fsp->fh->fd != -1) { /* File was created. Inherit from parent directory. */ - string_set(&fsp->fsp_name, fname); - inherit_new_acl(handle, fname, fsp, false); + status = fsp_set_smb_fname(fsp, smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + inherit_new_acl(handle, smb_fname, fsp, false); } - return fsp->fh->fd; } @@ -659,13 +649,24 @@ static int unlink_acl_tdb(vfs_handle_struct *handle, static int mkdir_acl_tdb(vfs_handle_struct *handle, const char *path, mode_t mode) { + struct smb_filename *smb_fname = NULL; int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode); + NTSTATUS status; if (ret == -1) { return ret; } + + status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + /* New directory - inherit from parent. */ - inherit_new_acl(handle, path, NULL, true); + inherit_new_acl(handle, smb_fname, NULL, true); + TALLOC_FREE(smb_fname); return ret; } @@ -713,15 +714,14 @@ static NTSTATUS fget_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, if (NT_STATUS_IS_OK(status)) { if (DEBUGLEVEL >= 10) { DEBUG(10,("fget_nt_acl_tdb: returning tdb sd for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, *ppdesc); } return NT_STATUS_OK; } DEBUG(10,("fget_nt_acl_tdb: failed to get tdb sd for file %s, Error %s\n", - fsp->fsp_name, - nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); @@ -765,7 +765,7 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_tdb: incoming sd for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } @@ -778,7 +778,6 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, /* Ensure owner and group are set. */ if (!psd->owner_sid || !psd->group_sid) { int ret; - SMB_STRUCT_STAT sbuf; DOM_SID owner_sid, group_sid; struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd); @@ -787,23 +786,19 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, } if (fsp->is_directory || fsp->fh->fd == -1) { if (fsp->posix_open) { - ret = vfs_lstat_smb_fname(fsp->conn, - fsp->fsp_name, - &sbuf); + ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { - ret = vfs_stat_smb_fname(fsp->conn, - fsp->fsp_name, - &sbuf); + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); } } else { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } if (ret == -1) { /* Lower level acl set succeeded, * so still return OK. */ return NT_STATUS_OK; } - create_file_sids(&sbuf, &owner_sid, &group_sid); + create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid); /* This is safe as nc_psd is discarded at fn exit. */ nc_psd->owner_sid = &owner_sid; nc_psd->group_sid = &group_sid; @@ -831,7 +826,7 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_tdb: storing tdb sd for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } @@ -913,7 +908,6 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl) { - SMB_STRUCT_STAT sbuf; struct db_context *db; int ret; @@ -921,14 +915,12 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, if (fsp->is_directory || fsp->fh->fd == -1) { if (fsp->posix_open) { - ret = vfs_lstat_smb_fname(fsp->conn,fsp->fsp_name, - &sbuf); + ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { - ret = vfs_stat_smb_fname(fsp->conn,fsp->fsp_name, - &sbuf); + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); } } else { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } if (ret == -1) { return -1; @@ -941,7 +933,7 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, return -1; } - acl_tdb_delete(handle, db, &sbuf); + acl_tdb_delete(handle, db, &fsp->fsp_name->st); return 0; } diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index eb6653bcd1..b18bc658ff 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -206,14 +206,14 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, int saved_errno = 0; DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", - (unsigned int)pblob->length, fsp->fsp_name)); + (unsigned int)pblob->length, fsp_str_dbg(fsp))); become_root(); if (fsp->fh->fd != -1) { ret = SMB_VFS_FSETXATTR(fsp, XATTR_NTACL_NAME, pblob->data, pblob->length, 0); } else { - ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name, + ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name, XATTR_NTACL_NAME, pblob->data, pblob->length, 0); } @@ -225,7 +225,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, errno = saved_errno; DEBUG(5, ("store_acl_blob_fsp: setting attr failed for file %s" "with error %s\n", - fsp->fsp_name, + fsp_str_dbg(fsp), strerror(errno) )); return map_nt_error_from_unix(errno); } @@ -284,7 +284,7 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, struct security_descriptor *pdesc_next = NULL; if (fsp && name == NULL) { - name = fsp->fsp_name; + name = fsp->fsp_name->base_name; } DEBUG(10, ("get_nt_acl_xattr_internal: name=%s\n", name)); @@ -408,7 +408,7 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx, *********************************************************************/ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, - const char *fname, + struct smb_filename *smb_fname, files_struct *fsp, bool container) { @@ -422,7 +422,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, char *parent_name; uint8_t hash[16]; - if (!parent_dirname(ctx, fname, &parent_name, NULL)) { + if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; } @@ -468,23 +468,22 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, } if (!psd || psd->dacl == NULL) { - SMB_STRUCT_STAT sbuf; int ret; TALLOC_FREE(psd); if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &smb_fname->st); } else { if (fsp && fsp->posix_open) { - ret = vfs_lstat_smb_fname(handle->conn,fname, &sbuf); + ret = SMB_VFS_LSTAT(handle->conn, smb_fname); } else { - ret = vfs_stat_smb_fname(handle->conn,fname, &sbuf); + ret = SMB_VFS_STAT(handle->conn, smb_fname); } } if (ret == -1) { return map_nt_error_from_unix(errno); } - psd = default_file_sd(ctx, &sbuf); + psd = default_file_sd(ctx, &smb_fname->st); if (!psd) { return NT_STATUS_NO_MEMORY; } @@ -503,7 +502,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, &pdesc_next); } else { status = SMB_VFS_NEXT_GET_NT_ACL(handle, - fname, + smb_fname->base_name, HASH_SECURITY_INFO, &pdesc_next); } @@ -523,7 +522,8 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp) { return store_acl_blob_fsp(handle, fsp, &blob); } else { - return store_acl_blob_pathname(handle, fname, &blob); + return store_acl_blob_pathname(handle, smb_fname->base_name, + &blob); } } @@ -591,8 +591,12 @@ static int open_acl_xattr(vfs_handle_struct *handle, if (!file_existed && fsp->fh->fd != -1) { /* File was created. Inherit from parent directory. */ - string_set(&fsp->fsp_name, fname); - inherit_new_acl(handle, fname, fsp, false); + status = fsp_set_smb_fname(fsp, smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + inherit_new_acl(handle, smb_fname, fsp, false); } return fsp->fh->fd; @@ -600,13 +604,24 @@ static int open_acl_xattr(vfs_handle_struct *handle, static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t mode) { + struct smb_filename *smb_fname = NULL; int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode); + NTSTATUS status; if (ret == -1) { return ret; } + + status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + /* New directory - inherit from parent. */ - inherit_new_acl(handle, path, NULL, true); + inherit_new_acl(handle, smb_fname, NULL, true); + TALLOC_FREE(smb_fname); return ret; } @@ -646,7 +661,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } @@ -654,7 +669,6 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, /* Ensure owner and group are set. */ if (!psd->owner_sid || !psd->group_sid) { int ret; - SMB_STRUCT_STAT sbuf; DOM_SID owner_sid, group_sid; struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd); @@ -663,19 +677,19 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, } if (fsp->is_directory || fsp->fh->fd == -1) { if (fsp->posix_open) { - ret = vfs_lstat_smb_fname(fsp->conn,fsp->fsp_name, &sbuf); + ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { - ret = vfs_stat_smb_fname(fsp->conn,fsp->fsp_name, &sbuf); + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); } } else { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } if (ret == -1) { /* Lower level acl set succeeded, * so still return OK. */ return NT_STATUS_OK; } - create_file_sids(&sbuf, &owner_sid, &group_sid); + create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid); /* This is safe as nc_psd is discarded at fn exit. */ nc_psd->owner_sid = &owner_sid; nc_psd->group_sid = &group_sid; @@ -723,7 +737,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c index 55371c60f5..e6f43c9680 100644 --- a/source3/modules/vfs_afsacl.c +++ b/source3/modules/vfs_afsacl.c @@ -655,18 +655,17 @@ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl, static size_t afs_to_nt_acl(struct afs_acl *afs_acl, struct connection_struct *conn, - const char *name, + struct smb_filename *smb_fname, uint32 security_info, struct security_descriptor **ppdesc) { - SMB_STRUCT_STAT sbuf; - /* Get the stat struct for the owner info. */ - if(vfs_stat_smb_fname(conn, name, &sbuf) != 0) { + if(SMB_VFS_STAT(conn, smb_fname) != 0) { return 0; } - return afs_to_nt_acl_common(afs_acl, &sbuf, security_info, ppdesc); + return afs_to_nt_acl_common(afs_acl, &smb_fname->st, security_info, + ppdesc); } static size_t afs_fto_nt_acl(struct afs_acl *afs_acl, @@ -905,7 +904,7 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, ZERO_STRUCT(dir_acl); ZERO_STRUCT(file_acl); - name = talloc_strdup(talloc_tos(), fsp->fsp_name); + name = talloc_strdup(talloc_tos(), fsp->fsp_name->base_name); if (!name) { return NT_STATUS_NO_MEMORY; } @@ -925,7 +924,7 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, } if (!afs_get_afs_acl(name, &old_afs_acl)) { - DEBUG(3, ("Could not get old ACL of %s\n", fsp->fsp_name)); + DEBUG(3, ("Could not get old ACL of %s\n", fsp_str_dbg(fsp))); goto done; } @@ -941,7 +940,8 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, } free_afs_acl(&dir_acl); - if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd, + if (!nt_to_afs_acl(fsp->fsp_name->base_name, + security_info_sent, psd, nt_to_afs_dir_rights, &dir_acl)) goto done; } else { @@ -956,7 +956,8 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, } free_afs_acl(&file_acl); - if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd, + if (!nt_to_afs_acl(fsp->fsp_name->base_name, + security_info_sent, psd, nt_to_afs_file_rights, &file_acl)) goto done; } @@ -997,11 +998,11 @@ static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle, struct afs_acl acl; size_t sd_size; - DEBUG(5, ("afsacl_fget_nt_acl: %s\n", fsp->fsp_name)); + DEBUG(5, ("afsacl_fget_nt_acl: %s\n", fsp_str_dbg(fsp))); sidpts = lp_parm_bool(SNUM(fsp->conn), "afsacl", "sidpts", False); - if (!afs_get_afs_acl(fsp->fsp_name, &acl)) { + if (!afs_get_afs_acl(fsp->fsp_name->base_name, &acl)) { return NT_STATUS_ACCESS_DENIED; } @@ -1018,6 +1019,8 @@ static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle, { struct afs_acl acl; size_t sd_size; + struct smb_filename *smb_fname = NULL; + NTSTATUS status; DEBUG(5, ("afsacl_get_nt_acl: %s\n", name)); @@ -1027,8 +1030,16 @@ static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle, return NT_STATUS_ACCESS_DENIED; } - sd_size = afs_to_nt_acl(&acl, handle->conn, name, security_info, + status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + free_afs_acl(&acl); + return status; + } + + sd_size = afs_to_nt_acl(&acl, handle->conn, smb_fname, security_info, ppdesc); + TALLOC_FREE(smb_fname); free_afs_acl(&acl); diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c index 5ebc3a12f8..01de33ed0b 100644 --- a/source3/modules/vfs_aixacl2.c +++ b/source3/modules/vfs_aixacl2.c @@ -162,7 +162,8 @@ static NTSTATUS aixjfs2_fget_nt_acl(vfs_handle_struct *handle, bool retryPosix = False; *ppdesc = NULL; - result = aixjfs2_get_nfs4_acl(fsp->fsp_name, &pacl, &retryPosix); + result = aixjfs2_get_nfs4_acl(fsp->fsp_name->base_name, &pacl, + &retryPosix); if (retryPosix) { DEBUG(10, ("retrying with posix acl...\n")); @@ -258,7 +259,7 @@ SMB_ACL_T aixjfs2_sys_acl_get_fd(vfs_handle_struct *handle, acl_type_t aixjfs2_type; aixjfs2_type.u64 = ACL_AIXC; - return aixjfs2_get_posix_acl(fsp->fsp_name, aixjfs2_type); + return aixjfs2_get_posix_acl(fsp->fsp_name->base_name, aixjfs2_type); } /* @@ -304,7 +305,7 @@ static bool aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) int rc; acl_type_t acltype; - DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp->fsp_name)); + DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp_str_dbg(fsp))); /* no need to be freed which is alloced with mem_ctx */ mem_ctx = talloc_tos(); @@ -353,7 +354,7 @@ static bool aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) /* won't set S_ISUID - the only one JFS2/NFS4 accepts */ rc = aclx_put( - fsp->fsp_name, + fsp->fsp_name->base_name, SET_ACL, /* set only the ACL, not mode bits */ acltype, /* not a pointer !!! */ jfs2acl, @@ -444,9 +445,10 @@ int aixjfs2_sys_acl_set_fd(vfs_handle_struct *handle, acl_type_t acl_type_info; int rc; - DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp->fsp_name)); + DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp_str_dbg(fsp))); - rc = aixjfs2_query_acl_support(fsp->fsp_name, ACL_AIXC, &acl_type_info); + rc = aixjfs2_query_acl_support(fsp->fsp_name->base_name, ACL_AIXC, + &acl_type_info); if (rc) { DEBUG(8, ("jfs2_set_nt_acl: AIXC support not found\n")); return -1; @@ -466,7 +468,7 @@ int aixjfs2_sys_acl_set_fd(vfs_handle_struct *handle, ); if (rc) { DEBUG(2, ("aclx_fput failed with %s for %s\n", - strerror(errno), fsp->fsp_name)); + strerror(errno), fsp_str_dbg(fsp))); return -1; } diff --git a/source3/modules/vfs_audit.c b/source3/modules/vfs_audit.c index cf2e27301d..dab3d78cec 100644 --- a/source3/modules/vfs_audit.c +++ b/source3/modules/vfs_audit.c @@ -237,7 +237,7 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n", - fsp->fsp_name, mode, + fsp->fsp_name->base_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -251,7 +251,7 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode); syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n", - fsp->fsp_name, mode, + fsp->fsp_name->base_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); diff --git a/source3/modules/vfs_cacheprime.c b/source3/modules/vfs_cacheprime.c index 71b850505a..3997dcbcfc 100644 --- a/source3/modules/vfs_cacheprime.c +++ b/source3/modules/vfs_cacheprime.c @@ -72,7 +72,7 @@ static bool prime_cache( DEBUG(module_debug, ("%s: doing readahead of %lld bytes at %lld for %s\n", MODULE, (long long)g_readsz, (long long)*last, - fsp->fsp_name)); + fsp_str_dbg(fsp))); nread = sys_pread(fsp->fh->fd, g_readbuf, g_readsz, *last); if (nread < 0) { diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index bb7853b926..d6a66b01de 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -866,7 +866,9 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs uint64_t space_avail; uint64_t bsize,dfree,dsize; - space_avail = get_dfree_info(fsp->conn,fsp->fsp_name,false,&bsize,&dfree,&dsize); + space_avail = get_dfree_info(fsp->conn, + fsp->fsp_name->base_name, false, + &bsize, &dfree, &dsize); /* space_avail is 1k blocks */ if (space_avail == (uint64_t)-1 || ((uint64_t)space_to_write/1024 > space_avail) ) { diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c index 68b85516ea..c9d1862fa4 100644 --- a/source3/modules/vfs_extd_audit.c +++ b/source3/modules/vfs_extd_audit.c @@ -304,12 +304,12 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod if (lp_syslog() > 0) { syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n", - fsp->fsp_name, mode, + fsp->fsp_name->base_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s", - fsp->fsp_name, (unsigned int)mode, + fsp_str_dbg(fsp), (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); @@ -324,12 +324,12 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t if (lp_syslog() > 0) { syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n", - fsp->fsp_name, mode, + fsp->fsp_name->base_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, (unsigned int)mode, + fsp_str_dbg(fsp), (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index bf53ae269c..76fbc8a8ae 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -419,6 +419,13 @@ static const char *smb_fname_str_do_log(const struct smb_filename *smb_fname) return fname; } +/** + * Return an fsp debug string using the do_log_ctx() + */ +static const char *fsp_str_do_log(const struct files_struct *fsp) +{ + return smb_fname_str_do_log(fsp->fsp_name); +} /* Free function for the private data. */ @@ -736,7 +743,8 @@ static int smb_full_audit_close(vfs_handle_struct *handle, files_struct *fsp) result = SMB_VFS_NEXT_CLOSE(handle, fsp); - do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -748,7 +756,8 @@ static ssize_t smb_full_audit_read(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_READ(handle, fsp, data, n); - do_log(SMB_VFS_OP_READ, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_READ, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -760,7 +769,8 @@ static ssize_t smb_full_audit_pread(vfs_handle_struct *handle, files_struct *fsp result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); - do_log(SMB_VFS_OP_PREAD, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_PREAD, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -772,7 +782,8 @@ static ssize_t smb_full_audit_write(vfs_handle_struct *handle, files_struct *fsp result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n); - do_log(SMB_VFS_OP_WRITE, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_WRITE, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -785,7 +796,8 @@ static ssize_t smb_full_audit_pwrite(vfs_handle_struct *handle, files_struct *fs result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); - do_log(SMB_VFS_OP_PWRITE, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_PWRITE, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -798,7 +810,7 @@ static SMB_OFF_T smb_full_audit_lseek(vfs_handle_struct *handle, files_struct *f result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence); do_log(SMB_VFS_OP_LSEEK, (result != (ssize_t)-1), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -813,7 +825,7 @@ static ssize_t smb_full_audit_sendfile(vfs_handle_struct *handle, int tofd, result = SMB_VFS_NEXT_SENDFILE(handle, tofd, fromfsp, hdr, offset, n); do_log(SMB_VFS_OP_SENDFILE, (result >= 0), handle, - "%s", fromfsp->fsp_name); + "%s", fsp_str_do_log(fromfsp)); return result; } @@ -828,7 +840,7 @@ static ssize_t smb_full_audit_recvfile(vfs_handle_struct *handle, int fromfd, result = SMB_VFS_NEXT_RECVFILE(handle, fromfd, tofsp, offset, n); do_log(SMB_VFS_OP_RECVFILE, (result >= 0), handle, - "%s", tofsp->fsp_name); + "%s", fsp_str_do_log(tofsp)); return result; } @@ -854,7 +866,8 @@ static int smb_full_audit_fsync(vfs_handle_struct *handle, files_struct *fsp) result = SMB_VFS_NEXT_FSYNC(handle, fsp); - do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -879,7 +892,8 @@ static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); - do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -942,7 +956,7 @@ static int smb_full_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); do_log(SMB_VFS_OP_FCHMOD, (result >= 0), handle, - "%s|%o", fsp->fsp_name, mode); + "%s|%o", fsp_str_do_log(fsp), mode); return result; } @@ -968,7 +982,7 @@ static int smb_full_audit_fchown(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid); do_log(SMB_VFS_OP_FCHOWN, (result >= 0), handle, "%s|%ld|%ld", - fsp->fsp_name, (long int)uid, (long int)gid); + fsp_str_do_log(fsp), (long int)uid, (long int)gid); return result; } @@ -1032,7 +1046,7 @@ static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp result = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, len); do_log(SMB_VFS_OP_FTRUNCATE, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1044,7 +1058,7 @@ static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type); - do_log(SMB_VFS_OP_LOCK, result, handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_LOCK, result, handle, "%s", fsp_str_do_log(fsp)); return result; } @@ -1058,7 +1072,7 @@ static int smb_full_audit_kernel_flock(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode); do_log(SMB_VFS_OP_KERNEL_FLOCK, (result >= 0), handle, "%s", - fsp->fsp_name); + fsp_str_do_log(fsp)); return result; } @@ -1071,7 +1085,7 @@ static int smb_full_audit_linux_setlease(vfs_handle_struct *handle, files_struct result = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype); do_log(SMB_VFS_OP_LINUX_SETLEASE, (result >= 0), handle, "%s", - fsp->fsp_name); + fsp_str_do_log(fsp)); return result; } @@ -1083,7 +1097,7 @@ static bool smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid); - do_log(SMB_VFS_OP_GETLOCK, result, handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_GETLOCK, result, handle, "%s", fsp_str_do_log(fsp)); return result; } @@ -1256,7 +1270,7 @@ static NTSTATUS smb_full_audit_brl_lock_windows(struct vfs_handle_struct *handle blocking_lock, blr); do_log(SMB_VFS_OP_BRL_LOCK_WINDOWS, NT_STATUS_IS_OK(result), handle, - "%s:%llu-%llu. type=%d. blocking=%d", br_lck->fsp->fsp_name, + "%s:%llu-%llu. type=%d. blocking=%d", fsp_str_do_log(br_lck->fsp), plock->start, plock->size, plock->lock_type, blocking_lock ); return result; @@ -1273,7 +1287,7 @@ static bool smb_full_audit_brl_unlock_windows(struct vfs_handle_struct *handle, plock); do_log(SMB_VFS_OP_BRL_UNLOCK_WINDOWS, (result == 0), handle, - "%s:%llu-%llu:%d", br_lck->fsp->fsp_name, plock->start, + "%s:%llu-%llu:%d", fsp_str_do_log(br_lck->fsp), plock->start, plock->size, plock->lock_type); return result; @@ -1289,7 +1303,7 @@ static bool smb_full_audit_brl_cancel_windows(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr); do_log(SMB_VFS_OP_BRL_CANCEL_WINDOWS, (result == 0), handle, - "%s:%llu-%llu:%d", br_lck->fsp->fsp_name, plock->start, + "%s:%llu-%llu:%d", fsp_str_do_log(br_lck->fsp), plock->start, plock->size); return result; @@ -1304,7 +1318,7 @@ static bool smb_full_audit_strict_lock(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock); do_log(SMB_VFS_OP_STRICT_LOCK, result, handle, - "%s:%llu-%llu:%d", fsp->fsp_name, plock->start, + "%s:%llu-%llu:%d", fsp_str_do_log(fsp), plock->start, plock->size); return result; @@ -1317,7 +1331,7 @@ static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle, SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock); do_log(SMB_VFS_OP_STRICT_UNLOCK, true, handle, - "%s:%llu-%llu:%d", fsp->fsp_name, plock->start, + "%s:%llu-%llu:%d", fsp_str_do_log(fsp), plock->start, plock->size); return; @@ -1332,7 +1346,7 @@ static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_stru result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); do_log(SMB_VFS_OP_FGET_NT_ACL, NT_STATUS_IS_OK(result), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1360,7 +1374,8 @@ static NTSTATUS smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_stru result = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); - do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -1386,7 +1401,7 @@ static int smb_full_audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fs result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode); do_log(SMB_VFS_OP_FCHMOD_ACL, (result >= 0), handle, - "%s|%o", fsp->fsp_name, mode); + "%s|%o", fsp_str_do_log(fsp), mode); return result; } @@ -1475,7 +1490,7 @@ static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle, result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp); do_log(SMB_VFS_OP_SYS_ACL_GET_FD, (result != NULL), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1635,7 +1650,7 @@ static int smb_full_audit_sys_acl_set_fd(vfs_handle_struct *handle, files_struct result = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl); do_log(SMB_VFS_OP_SYS_ACL_SET_FD, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1749,7 +1764,7 @@ static ssize_t smb_full_audit_fgetxattr(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size); do_log(SMB_VFS_OP_FGETXATTR, (result >= 0), handle, - "%s|%s", fsp->fsp_name, name); + "%s|%s", fsp_str_do_log(fsp), name); return result; } @@ -1787,7 +1802,7 @@ static ssize_t smb_full_audit_flistxattr(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size); do_log(SMB_VFS_OP_FLISTXATTR, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1829,7 +1844,7 @@ static int smb_full_audit_fremovexattr(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name); do_log(SMB_VFS_OP_FREMOVEXATTR, (result >= 0), handle, - "%s|%s", fsp->fsp_name, name); + "%s|%s", fsp_str_do_log(fsp), name); return result; } @@ -1875,7 +1890,7 @@ static int smb_full_audit_fsetxattr(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, value, size, flags); do_log(SMB_VFS_OP_FSETXATTR, (result >= 0), handle, - "%s|%s", fsp->fsp_name, name); + "%s|%s", fsp_str_do_log(fsp), name); return result; } @@ -1886,7 +1901,7 @@ static int smb_full_audit_aio_read(struct vfs_handle_struct *handle, struct file result = SMB_VFS_NEXT_AIO_READ(handle, fsp, aiocb); do_log(SMB_VFS_OP_AIO_READ, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1897,7 +1912,7 @@ static int smb_full_audit_aio_write(struct vfs_handle_struct *handle, struct fil result = SMB_VFS_NEXT_AIO_WRITE(handle, fsp, aiocb); do_log(SMB_VFS_OP_AIO_WRITE, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1908,7 +1923,7 @@ static ssize_t smb_full_audit_aio_return(struct vfs_handle_struct *handle, struc result = SMB_VFS_NEXT_AIO_RETURN(handle, fsp, aiocb); do_log(SMB_VFS_OP_AIO_RETURN, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1919,7 +1934,7 @@ static int smb_full_audit_aio_cancel(struct vfs_handle_struct *handle, struct fi result = SMB_VFS_NEXT_AIO_CANCEL(handle, fsp, aiocb); do_log(SMB_VFS_OP_AIO_CANCEL, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1930,7 +1945,7 @@ static int smb_full_audit_aio_error(struct vfs_handle_struct *handle, struct fil result = SMB_VFS_NEXT_AIO_ERROR(handle, fsp, aiocb); do_log(SMB_VFS_OP_AIO_ERROR, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1941,7 +1956,7 @@ static int smb_full_audit_aio_fsync(struct vfs_handle_struct *handle, struct fil result = SMB_VFS_NEXT_AIO_FSYNC(handle, fsp, op, aiocb); do_log(SMB_VFS_OP_AIO_FSYNC, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1952,7 +1967,7 @@ static int smb_full_audit_aio_suspend(struct vfs_handle_struct *handle, struct f result = SMB_VFS_NEXT_AIO_SUSPEND(handle, fsp, aiocb, n, ts); do_log(SMB_VFS_OP_AIO_SUSPEND, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1964,7 +1979,7 @@ static bool smb_full_audit_aio_force(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_AIO_FORCE(handle, fsp); do_log(SMB_VFS_OP_AIO_FORCE, result, handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index ffa8db00b3..cde80f0021 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -303,7 +303,7 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, int result; *ppdesc = NULL; - result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl); + result = gpfs_get_nfs4_acl(fsp->fsp_name->base_name, &pacl); if (result == 0) return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); @@ -389,7 +389,7 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) "merge_writeappend", True)) { DEBUG(2, ("vfs_gpfs.c: file [%s]: ACE contains " "WRITE^APPEND, setting WRITE|APPEND\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); gace->aceMask |= ACE4_MASK_WRITE|ACE4_MASK_APPEND; } @@ -423,7 +423,8 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) gacl->acl_nace++; } - ret = smbd_gpfs_putacl(fsp->fsp_name, GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl); + ret = smbd_gpfs_putacl(fsp->fsp_name->base_name, + GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl); if (ret != 0) { DEBUG(8, ("gpfs_putacl failed with %s\n", strerror(errno))); gpfs_dumpacl(8, gacl); @@ -439,7 +440,7 @@ static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_i struct gpfs_acl *acl; NTSTATUS result = NT_STATUS_ACCESS_DENIED; - acl = gpfs_getacl_alloc(fsp->fsp_name, 0); + acl = gpfs_getacl_alloc(fsp->fsp_name->base_name, 0); if (acl == NULL) return result; @@ -594,7 +595,8 @@ static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle, static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) { - return gpfsacl_get_posix_acl(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS); + return gpfsacl_get_posix_acl(fsp->fsp_name->base_name, + GPFS_ACL_TYPE_ACCESS); } static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl, @@ -707,7 +709,8 @@ static int gpfsacl_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl) { - return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name, SMB_ACL_TYPE_ACCESS, theacl); + return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name->base_name, + SMB_ACL_TYPE_ACCESS, theacl); } static int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle, @@ -764,6 +767,8 @@ static int gpfsacl_emu_chmod(const char *path, mode_t mode) int i; files_struct fake_fsp; /* TODO: rationalize parametrization */ SMB4ACE_T *smbace; + struct smb_filename *smb_fname = NULL; + NTSTATUS status; DEBUG(10, ("gpfsacl_emu_chmod invoked for %s mode %o\n", path, mode)); @@ -833,11 +838,19 @@ static int gpfsacl_emu_chmod(const char *path, mode_t mode) /* don't add complementary DENY ACEs here */ ZERO_STRUCT(fake_fsp); - fake_fsp.fsp_name = (char *)path; /* no file_new is needed here */ - + status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL, + &fake_fsp.fsp_name); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } /* put the acl */ - if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False) + if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False) { + TALLOC_FREE(fake_fsp.fsp_name); return -1; + } + + TALLOC_FREE(fake_fsp.fsp_name); return 0; /* ok for [f]chmod */ } @@ -875,7 +888,7 @@ static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t return 0; } - rc = gpfsacl_emu_chmod(fsp->fsp_name, mode); + rc = gpfsacl_emu_chmod(fsp->fsp_name->base_name, mode); if (rc == 1) return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); return rc; diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c index 35341a5c3e..32e8539202 100644 --- a/source3/modules/vfs_hpuxacl.c +++ b/source3/modules/vfs_hpuxacl.c @@ -201,23 +201,23 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle, DEBUG(10, ("redirecting call of hpuxacl_sys_acl_get_fd to " "hpuxacl_sys_acl_get_file (no facl syscall on HPUX).\n")); - return hpuxacl_sys_acl_get_file(handle, file_struct_p->fsp_name, - SMB_ACL_TYPE_ACCESS); + return hpuxacl_sys_acl_get_file(handle, + file_struct_p->fsp_name->base_name, + SMB_ACL_TYPE_ACCESS); } int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, - const char *name, + struct smb_filename *smb_fname, SMB_ACL_TYPE_T type, SMB_ACL_T theacl) { int ret = -1; - SMB_STRUCT_STAT s; HPUX_ACL_T hpux_acl = NULL; int count; DEBUG(10, ("hpuxacl_sys_acl_set_file called for file '%s'\n", - name)); + smb_fname_str_dbg(smb_fname))); if(hpux_acl_call_present() == False) { @@ -248,11 +248,11 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, * that has _not_ been specified in "type" from the file first * and concatenate it with the acl provided. */ - if (vfs_stat_smb_fname(handle->conn, name, &s) != 0) { + if (SMB_VFS_STAT(handle->conn, smb_fname) != 0) { DEBUG(10, ("Error in stat call: %s\n", strerror(errno))); goto done; } - if (S_ISDIR(s.st_ex_mode)) { + if (S_ISDIR(smb_fname->st.st_ex_mode)) { HPUX_ACL_T other_acl; int other_count; SMB_ACL_TYPE_T other_type; @@ -261,7 +261,8 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, ? SMB_ACL_TYPE_DEFAULT : SMB_ACL_TYPE_ACCESS; DEBUGADD(10, ("getting acl from filesystem\n")); - if (!hpux_acl_get_file(name, &other_acl, &other_count)) { + if (!hpux_acl_get_file(smb_fname->base_name, &other_acl, + &other_count)) { DEBUG(10, ("error getting acl from directory\n")); goto done; } @@ -289,7 +290,8 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, } DEBUG(10, ("resulting acl is valid.\n")); - ret = acl(CONST_DISCARD(char *, name), ACL_SET, count, hpux_acl); + ret = acl(CONST_DISCARD(char *, smb_fname->base_name), ACL_SET, count, + hpux_acl); if (ret != 0) { DEBUG(0, ("ERROR calling acl: %s\n", strerror(errno))); } diff --git a/source3/modules/vfs_hpuxacl.h b/source3/modules/vfs_hpuxacl.h index 07b32d628c..9baed5790a 100644 --- a/source3/modules/vfs_hpuxacl.h +++ b/source3/modules/vfs_hpuxacl.h @@ -41,7 +41,7 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp); int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, - const char *name, + struct smb_filename *smb_fname, SMB_ACL_TYPE_T type, SMB_ACL_T theacl); diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 29247ac7c2..7c338e7268 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -406,8 +406,8 @@ static int shadow_copy2_lstat(vfs_handle_struct *handle, static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf) { int ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); - if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name)) { - convert_sbuf(handle, fsp->fsp_name, sbuf); + if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name->base_name)) { + convert_sbuf(handle, fsp->fsp_name->base_name, sbuf); } return ret; } diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c index a7fbeadbbe..6f7aee0e50 100644 --- a/source3/modules/vfs_smb_traffic_analyzer.c +++ b/source3/modules/vfs_smb_traffic_analyzer.c @@ -336,11 +336,11 @@ static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, \ ssize_t result; result = SMB_VFS_NEXT_READ(handle, fsp, data, n); - DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp_str_dbg(fsp))); smb_traffic_analyzer_send_data(handle, result, - fsp->fsp_name, + fsp->fsp_name->base_name, false); return result; } @@ -353,11 +353,12 @@ static ssize_t smb_traffic_analyzer_pread(vfs_handle_struct *handle, \ result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); - DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n", + fsp_str_dbg(fsp))); smb_traffic_analyzer_send_data(handle, result, - fsp->fsp_name, + fsp->fsp_name->base_name, false); return result; @@ -370,11 +371,12 @@ static ssize_t smb_traffic_analyzer_write(vfs_handle_struct *handle, \ result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n); - DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n", + fsp_str_dbg(fsp))); smb_traffic_analyzer_send_data(handle, result, - fsp->fsp_name, + fsp->fsp_name->base_name, true); return result; } @@ -386,11 +388,11 @@ static ssize_t smb_traffic_analyzer_pwrite(vfs_handle_struct *handle, \ result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); - DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp_str_dbg(fsp))); smb_traffic_analyzer_send_data(handle, result, - fsp->fsp_name, + fsp->fsp_name->base_name, true); return result; } diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index eccc2379c9..c32c4f3190 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -128,27 +128,20 @@ static NTSTATUS streams_xattr_get_name(TALLOC_CTX *ctx, static bool streams_xattr_recheck(struct stream_io *sio) { NTSTATUS status; - struct smb_filename *smb_fname = NULL; char *xattr_name = NULL; if (sio->fsp->fsp_name == sio->fsp_name_ptr) { return true; } - status = create_synthetic_smb_fname_split(talloc_tos(), - sio->fsp->fsp_name, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return false; - } - - if (smb_fname->stream_name == NULL) { + if (sio->fsp->fsp_name->stream_name == NULL) { /* how can this happen */ errno = EINVAL; return false; } - status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name, + status = streams_xattr_get_name(talloc_tos(), + sio->fsp->fsp_name->stream_name, &xattr_name); if (!NT_STATUS_IS_OK(status)) { return false; @@ -159,10 +152,9 @@ static bool streams_xattr_recheck(struct stream_io *sio) sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp), xattr_name); sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp), - smb_fname->base_name); + sio->fsp->fsp_name->base_name); sio->fsp_name_ptr = sio->fsp->fsp_name; - TALLOC_FREE(smb_fname); TALLOC_FREE(xattr_name); if ((sio->xattr_name == NULL) || (sio->base == NULL)) { @@ -899,7 +891,8 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, sio->xattr_name, ea.value.data, ea.value.length, 0); } else { - ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name, + ret = SMB_VFS_SETXATTR(fsp->conn, + fsp->base_fsp->fsp_name->base_name, sio->xattr_name, ea.value.data, ea.value.length, 0); } @@ -963,8 +956,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle, (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); DEBUG(10, ("streams_xattr_ftruncate called for file %s offset %.0f\n", - fsp->fsp_name, - (double)offset )); + fsp_str_dbg(fsp), (double)offset)); if (sio == NULL) { return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset); @@ -1004,7 +996,8 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle, sio->xattr_name, ea.value.data, ea.value.length, 0); } else { - ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name, + ret = SMB_VFS_SETXATTR(fsp->conn, + fsp->base_fsp->fsp_name->base_name, sio->xattr_name, ea.value.data, ea.value.length, 0); } diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c index 57807105f6..753b2bcd26 100644 --- a/source3/modules/vfs_tsmsm.c +++ b/source3/modules/vfs_tsmsm.c @@ -273,7 +273,7 @@ static ssize_t tsmsm_aio_return(struct vfs_handle_struct *handle, struct files_s if(result >= 0) { notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, - fsp->fsp_name); + fsp->fsp_name->base_name); } return result; @@ -307,7 +307,7 @@ static ssize_t tsmsm_pread(struct vfs_handle_struct *handle, struct files_struct */ notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, - fsp->fsp_name); + fsp->fsp_name->base_name); } return result; @@ -325,7 +325,7 @@ static ssize_t tsmsm_pwrite(struct vfs_handle_struct *handle, struct files_struc */ notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, - fsp->fsp_name); + fsp->fsp_name->base_name); } return result; diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c index a5b0490c8d..a92d5dae26 100644 --- a/source3/modules/vfs_zfsacl.c +++ b/source3/modules/vfs_zfsacl.c @@ -145,14 +145,14 @@ static bool zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) SMB_ASSERT(i == naces); /* store acl */ - if(acl(fsp->fsp_name, ACE_SETACL, naces, acebuf)) { + if(acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf)) { if(errno == ENOSYS) { DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not " "supported on the filesystem where the file " - "reside", fsp->fsp_name)); + "reside", fsp_str_dbg(fsp))); } else { - DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp->fsp_name, - strerror(errno))); + DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp_str_dbg(fsp), + strerror(errno))); } return 0; } @@ -180,7 +180,8 @@ static NTSTATUS zfsacl_fget_nt_acl(struct vfs_handle_struct *handle, SMB4ACL_T *pacl; NTSTATUS status; - status = zfs_get_nt_acl_common(fsp->fsp_name, security_info, &pacl); + status = zfs_get_nt_acl_common(fsp->fsp_name->base_name, security_info, + &pacl); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c index a8e175a684..9185fc84b1 100644 --- a/source3/printing/printfsp.c +++ b/source3/printing/printfsp.c @@ -58,6 +58,13 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn, return NT_STATUS_ACCESS_DENIED; /* No errno around here */ } + status = create_synthetic_smb_fname(fsp, + print_job_fname(lp_const_servicename(SNUM(conn)), jobid), NULL, + NULL, &fsp->fsp_name); + if (!NT_STATUS_IS_OK(status)) { + pjob_delete(lp_const_servicename(SNUM(conn)), jobid); + return status; + } /* setup a full fsp */ fsp->fh->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid); GetTimeOfDay(&fsp->open_time); @@ -72,7 +79,6 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn, fsp->oplock_type = NO_OPLOCK; fsp->sent_oplock_break = NO_BREAK_SENT; fsp->is_directory = False; - string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid)); fsp->wcp = NULL; SMB_VFS_FSTAT(fsp, psbuf); fsp->mode = psbuf->st_ex_mode; @@ -98,7 +104,7 @@ void print_fsp_end(files_struct *fsp, enum file_close_type close_type) } if (fsp->fsp_name) { - string_free(&fsp->fsp_name); + TALLOC_FREE(fsp->fsp_name); } if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) { diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index 33ced8fa54..cd550a4f48 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -317,11 +317,6 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c if (fsp == NULL) { return NT_STATUS_NO_MEMORY; } - fsp->fsp_name = SMB_STRDUP(argv[1]); - if (fsp->fsp_name == NULL) { - SAFE_FREE(fsp); - return NT_STATUS_NO_MEMORY; - } fsp->fh = SMB_MALLOC_P(struct fd_handle); if (fsp->fh == NULL) { SAFE_FREE(fsp->fsp_name); @@ -333,18 +328,18 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c status = create_synthetic_smb_fname_split(mem_ctx, argv[1], NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { - SAFE_FREE(fsp->fsp_name); SAFE_FREE(fsp); return status; } + fsp->fsp_name = smb_fname; + fsp->fh->fd = SMB_VFS_OPEN(vfs->conn, smb_fname, fsp, flags, mode); - TALLOC_FREE(smb_fname); if (fsp->fh->fd == -1) { printf("open: error=%d (%s)\n", errno, strerror(errno)); SAFE_FREE(fsp->fh); - SAFE_FREE(fsp->fsp_name); SAFE_FREE(fsp); + TALLOC_FREE(smb_fname); return NT_STATUS_UNSUCCESSFUL; } @@ -415,7 +410,7 @@ static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, else printf("close: ok\n"); - SAFE_FREE(vfs->files[fd]->fsp_name); + TALLOC_FREE(vfs->files[fd]->fsp_name); SAFE_FREE(vfs->files[fd]->fh); SAFE_FREE(vfs->files[fd]); vfs->files[fd] = NULL; -- cgit From 82c3f505fe2e50022b5102e6388dc3b830d235da Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 15:10:35 -0700 Subject: s3: Move is_ntfs_stream*() to filename.c --- source3/include/proto.h | 4 ++-- source3/smbd/filename.c | 24 ++++++++++++++++++++++++ source3/smbd/nttrans.c | 24 ------------------------ 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 830d2284c4..cdc58437f0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6325,6 +6325,8 @@ const char *smb_fname_str_dbg(const struct smb_filename *smb_fname); NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname_in, struct smb_filename **smb_fname_out); +bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname); +bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname); NTSTATUS unix_convert(TALLOC_CTX *ctx, connection_struct *conn, const char *orig_path, @@ -6548,8 +6550,6 @@ void send_nt_replies(connection_struct *conn, struct smb_request *req, NTSTATUS nt_error, char *params, int paramsize, char *pdata, int datasize); -bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname); -bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname); void reply_ntcreate_and_X(struct smb_request *req); void reply_ntcancel(struct smb_request *req); void reply_ntrename(struct smb_request *req); diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 29ebc37d1a..1eb6ce5065 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -275,6 +275,30 @@ NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, return NT_STATUS_NO_MEMORY; } +/**************************************************************************** + Simple check to determine if the filename is a stream. + ***************************************************************************/ +bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) +{ + if (lp_posix_pathnames()) { + return false; + } + + return smb_fname->stream_name; +} + +/**************************************************************************** + Returns true if the filename's stream == "::$DATA" + ***************************************************************************/ +bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) +{ + if (!is_ntfs_stream_smb_fname(smb_fname)) { + return false; + } + + return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0; +} + /**************************************************************************** This routine is called to convert names from the dos namespace to unix namespace. It needs to handle any case conversions, mangling, format changes, diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index ff76b7a21f..ecb88296ca 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -271,30 +271,6 @@ void send_nt_replies(connection_struct *conn, } } -/**************************************************************************** - Simple check to determine if the filename is a stream. - ***************************************************************************/ -bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) -{ - if (lp_posix_pathnames()) { - return false; - } - - return smb_fname->stream_name; -} - -/**************************************************************************** - Returns true if the filename's stream == "::$DATA" - ***************************************************************************/ -bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) -{ - if (!is_ntfs_stream_smb_fname(smb_fname)) { - return false; - } - - return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0; -} - /**************************************************************************** Reply to an NT create and X call on a pipe ****************************************************************************/ -- cgit From 841efce8b5e931a7ec910afb7d0d8b6a123c6900 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 15:35:08 -0700 Subject: s3: Separate out a new file: filename_utils.c This is to ease the linking pain of everything that links LOCKING_OBJ --- source3/Makefile.in | 14 +-- source3/include/proto.h | 43 +++++---- source3/smbd/filename.c | 219 ------------------------------------------- source3/smbd/filename_util.c | 194 ++++++++++++++++++++++++++++++++++++++ source3/smbd/files.c | 9 -- source3/smbd/vfs.c | 55 +++++++++++ 6 files changed, 280 insertions(+), 254 deletions(-) create mode 100644 source3/smbd/filename_util.c diff --git a/source3/Makefile.in b/source3/Makefile.in index f6396ef157..e6d0cf00dd 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -667,6 +667,8 @@ OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o \ NOTIFY_OBJ = smbd/notify.o smbd/notify_inotify.o smbd/notify_internal.o +FNAME_UTIL_OBJ = smbd/filename_util.o + VFS_DEFAULT_OBJ = modules/vfs_default.o VFS_AUDIT_OBJ = modules/vfs_audit.o VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o @@ -786,7 +788,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \ $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \ - $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ + $(NOTIFY_OBJ) $(FNAME_UTIL_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \ $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \ $(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \ @@ -828,16 +830,16 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(PRINTBASE_OBJ) $(LIBSMB_O $(LOCKING_OBJ) $(PASSDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBMSRPC_OBJ) \ - $(PASSCHANGE_OBJ) $(LDB_OBJ) + $(PASSCHANGE_OBJ) $(LDB_OBJ) $(FNAME_UTIL_OBJ) STATUS_OBJ = utils/status.o utils/status_profile.o \ $(LOCKING_OBJ) $(PARAM_OBJ) \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ - $(LIBSAMBA_OBJ) + $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ - $(LIBSAMBA_OBJ) \ + $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) \ $(PRINTBASE_OBJ) SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \ @@ -1033,7 +1035,7 @@ MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIEN LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \ $(LIBSMB_OBJ) $(LDB_OBJ) $(LIB_NONSMBD_OBJ) \ - $(LIBNDR_GEN_OBJ0) + $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ) NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) \ @@ -1052,7 +1054,7 @@ LOG2PCAP_OBJ = utils/log2pcaphex.o LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ - $(LIBNDR_GEN_OBJ0) + $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ) SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \ diff --git a/source3/include/proto.h b/source3/include/proto.h index cdc58437f0..c26f2a7c3a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6307,6 +6307,24 @@ int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst); /* The following definitions come from smbd/filename.c */ +NTSTATUS unix_convert(TALLOC_CTX *ctx, + connection_struct *conn, + const char *orig_path, + struct smb_filename **smb_fname, + uint32_t ucf_flags); +NTSTATUS check_name(connection_struct *conn, const char *name); +int get_real_filename(connection_struct *conn, const char *path, + const char *name, TALLOC_CTX *mem_ctx, + char **found_name); +NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, + connection_struct *conn, + bool dfs_path, + const char *name_in, + struct smb_filename **pp_smb_fname, + char **pp_name); + +/* The following definitions come from smbd/filename_utils.c */ + NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname, char **full_name); NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name, @@ -6317,31 +6335,13 @@ NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx, const char *fname, const SMB_STRUCT_STAT *psbuf, struct smb_filename **smb_fname_out); -int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf); -int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf); const char *smb_fname_str_dbg(const struct smb_filename *smb_fname); +const char *fsp_str_dbg(const struct files_struct *fsp); NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname_in, struct smb_filename **smb_fname_out); bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname); bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname); -NTSTATUS unix_convert(TALLOC_CTX *ctx, - connection_struct *conn, - const char *orig_path, - struct smb_filename **smb_fname, - uint32_t ucf_flags); -NTSTATUS check_name(connection_struct *conn, const char *name); -int get_real_filename(connection_struct *conn, const char *path, - const char *name, TALLOC_CTX *mem_ctx, - char **found_name); -NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, - connection_struct *conn, - bool dfs_path, - const char *name_in, - struct smb_filename **pp_smb_fname, - char **pp_name); /* The following definitions come from smbd/files.c */ @@ -6370,7 +6370,6 @@ files_struct *file_fsp(struct smb_request *req, uint16 fid); NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, uint32 access_mask, uint32 share_access, uint32 create_options, files_struct *to); -const char *fsp_str_dbg(const struct files_struct *fsp); NTSTATUS fsp_set_smb_fname(struct files_struct *fsp, const struct smb_filename *smb_fname_in); @@ -7117,6 +7116,10 @@ char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf); int vfs_ChDir(connection_struct *conn, const char *path); char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn); NTSTATUS check_reduced_name(connection_struct *conn, const char *fname); +int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf); +int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf); /* The following definitions come from torture/denytest.c */ diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 1eb6ce5065..c05f0e659f 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -80,225 +80,6 @@ static NTSTATUS determine_path_error(const char *name, } } -/** - * XXX: This is temporary and there should be no callers of this outside of - * this file once smb_filename is plumbed through all path based operations. - * The one legitimate caller currently is smb_fname_str_dbg(), which this - * could be made static for. - */ -NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname, - char **full_name) -{ - if (smb_fname->stream_name) { - *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name, - smb_fname->stream_name); - } else { - *full_name = talloc_strdup(ctx, smb_fname->base_name); - } - - if (!*full_name) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -/** - * There are actually legitimate callers of this such as functions that - * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to - * operate on each stream. - */ -NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name, - const char *stream_name, - const SMB_STRUCT_STAT *psbuf, - struct smb_filename **smb_fname_out) -{ - struct smb_filename smb_fname_loc; - - ZERO_STRUCT(smb_fname_loc); - - /* Setup the base_name/stream_name. */ - smb_fname_loc.base_name = CONST_DISCARD(char *, base_name); - smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name); - - /* Copy the psbuf if one was given. */ - if (psbuf) - smb_fname_loc.st = *psbuf; - - /* Let copy_smb_filename() do the heavy lifting. */ - return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out); -} - -/** - * XXX: This is temporary and there should be no callers of this once - * smb_filename is plumbed through all path based operations. - */ -NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx, - const char *fname, - const SMB_STRUCT_STAT *psbuf, - struct smb_filename **smb_fname_out) -{ - NTSTATUS status; - const char *stream_name = NULL; - char *base_name = NULL; - - if (!lp_posix_pathnames()) { - stream_name = strchr_m(fname, ':'); - } - - /* Setup the base_name/stream_name. */ - if (stream_name) { - base_name = talloc_strndup(ctx, fname, - PTR_DIFF(stream_name, fname)); - } else { - base_name = talloc_strdup(ctx, fname); - } - - if (!base_name) { - return NT_STATUS_NO_MEMORY; - } - - status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf, - smb_fname_out); - TALLOC_FREE(base_name); - return status; -} - -/** - * XXX: This is temporary and there should be no callers of this once - * smb_filename is plumbed through all path based operations. - */ -int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf) -{ - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - int ret; - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; - } - - ret = SMB_VFS_STAT(conn, smb_fname); - if (ret != -1) { - *psbuf = smb_fname->st; - } - - TALLOC_FREE(smb_fname); - return ret; -} - -/** - * XXX: This is temporary and there should be no callers of this once - * smb_filename is plumbed through all path based operations. - */ -int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf) -{ - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - int ret; - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; - } - - ret = SMB_VFS_LSTAT(conn, smb_fname); - if (ret != -1) { - *psbuf = smb_fname->st; - } - - TALLOC_FREE(smb_fname); - return ret; -} - -/** - * Return a string using the debug_ctx() - */ -const char *smb_fname_str_dbg(const struct smb_filename *smb_fname) -{ - char *fname = NULL; - NTSTATUS status; - - if (smb_fname == NULL) { - return ""; - } - status = get_full_smb_filename(debug_ctx(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - return ""; - } - return fname; -} - -NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, - const struct smb_filename *smb_fname_in, - struct smb_filename **smb_fname_out) -{ - - *smb_fname_out = talloc_zero(ctx, struct smb_filename); - if (*smb_fname_out == NULL) { - return NT_STATUS_NO_MEMORY; - } - - if (smb_fname_in->base_name) { - (*smb_fname_out)->base_name = - talloc_strdup(*smb_fname_out, smb_fname_in->base_name); - if (!(*smb_fname_out)->base_name) - goto no_mem_err; - } - - if (smb_fname_in->stream_name) { - (*smb_fname_out)->stream_name = - talloc_strdup(*smb_fname_out, smb_fname_in->stream_name); - if (!(*smb_fname_out)->stream_name) - goto no_mem_err; - } - - if (smb_fname_in->original_lcomp) { - (*smb_fname_out)->original_lcomp = - talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp); - if (!(*smb_fname_out)->original_lcomp) - goto no_mem_err; - } - - (*smb_fname_out)->st = smb_fname_in->st; - return NT_STATUS_OK; - - no_mem_err: - TALLOC_FREE(*smb_fname_out); - return NT_STATUS_NO_MEMORY; -} - -/**************************************************************************** - Simple check to determine if the filename is a stream. - ***************************************************************************/ -bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) -{ - if (lp_posix_pathnames()) { - return false; - } - - return smb_fname->stream_name; -} - -/**************************************************************************** - Returns true if the filename's stream == "::$DATA" - ***************************************************************************/ -bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) -{ - if (!is_ntfs_stream_smb_fname(smb_fname)) { - return false; - } - - return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0; -} - /**************************************************************************** This routine is called to convert names from the dos namespace to unix namespace. It needs to handle any case conversions, mangling, format changes, diff --git a/source3/smbd/filename_util.c b/source3/smbd/filename_util.c new file mode 100644 index 0000000000..1a7af714de --- /dev/null +++ b/source3/smbd/filename_util.c @@ -0,0 +1,194 @@ +/* + Unix SMB/CIFS implementation. + Filename utility functions. + Copyright (C) Tim Prouty 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 . +*/ +#include "includes.h" + +/** + * XXX: This is temporary and there should be no callers of this outside of + * this file once smb_filename is plumbed through all path based operations. + * The one legitimate caller currently is smb_fname_str_dbg(), which this + * could be made static for. + */ +NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, + const struct smb_filename *smb_fname, + char **full_name) +{ + if (smb_fname->stream_name) { + *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name, + smb_fname->stream_name); + } else { + *full_name = talloc_strdup(ctx, smb_fname->base_name); + } + + if (!*full_name) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + +/** + * There are actually legitimate callers of this such as functions that + * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to + * operate on each stream. + */ +NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name, + const char *stream_name, + const SMB_STRUCT_STAT *psbuf, + struct smb_filename **smb_fname_out) +{ + struct smb_filename smb_fname_loc; + + ZERO_STRUCT(smb_fname_loc); + + /* Setup the base_name/stream_name. */ + smb_fname_loc.base_name = CONST_DISCARD(char *, base_name); + smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name); + + /* Copy the psbuf if one was given. */ + if (psbuf) + smb_fname_loc.st = *psbuf; + + /* Let copy_smb_filename() do the heavy lifting. */ + return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out); +} + +/** + * XXX: This is temporary and there should be no callers of this once + * smb_filename is plumbed through all path based operations. + */ +NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx, + const char *fname, + const SMB_STRUCT_STAT *psbuf, + struct smb_filename **smb_fname_out) +{ + NTSTATUS status; + const char *stream_name = NULL; + char *base_name = NULL; + + if (!lp_posix_pathnames()) { + stream_name = strchr_m(fname, ':'); + } + + /* Setup the base_name/stream_name. */ + if (stream_name) { + base_name = talloc_strndup(ctx, fname, + PTR_DIFF(stream_name, fname)); + } else { + base_name = talloc_strdup(ctx, fname); + } + + if (!base_name) { + return NT_STATUS_NO_MEMORY; + } + + status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf, + smb_fname_out); + TALLOC_FREE(base_name); + return status; +} + +/** + * Return a string using the debug_ctx() + */ +const char *smb_fname_str_dbg(const struct smb_filename *smb_fname) +{ + char *fname = NULL; + NTSTATUS status; + + if (smb_fname == NULL) { + return ""; + } + status = get_full_smb_filename(debug_ctx(), smb_fname, &fname); + if (!NT_STATUS_IS_OK(status)) { + return ""; + } + return fname; +} + +/** + * Return a debug string using the debug_ctx(). This can only be called from + * DEBUG() macros due to the debut_ctx(). + */ +const char *fsp_str_dbg(const struct files_struct *fsp) +{ + return smb_fname_str_dbg(fsp->fsp_name); +} + +NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, + const struct smb_filename *smb_fname_in, + struct smb_filename **smb_fname_out) +{ + + *smb_fname_out = talloc_zero(ctx, struct smb_filename); + if (*smb_fname_out == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (smb_fname_in->base_name) { + (*smb_fname_out)->base_name = + talloc_strdup(*smb_fname_out, smb_fname_in->base_name); + if (!(*smb_fname_out)->base_name) + goto no_mem_err; + } + + if (smb_fname_in->stream_name) { + (*smb_fname_out)->stream_name = + talloc_strdup(*smb_fname_out, smb_fname_in->stream_name); + if (!(*smb_fname_out)->stream_name) + goto no_mem_err; + } + + if (smb_fname_in->original_lcomp) { + (*smb_fname_out)->original_lcomp = + talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp); + if (!(*smb_fname_out)->original_lcomp) + goto no_mem_err; + } + + (*smb_fname_out)->st = smb_fname_in->st; + return NT_STATUS_OK; + + no_mem_err: + TALLOC_FREE(*smb_fname_out); + return NT_STATUS_NO_MEMORY; +} + +/**************************************************************************** + Simple check to determine if the filename is a stream. + ***************************************************************************/ +bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) +{ + if (lp_posix_pathnames()) { + return false; + } + + return smb_fname->stream_name; +} + +/**************************************************************************** + Returns true if the filename's stream == "::$DATA" + ***************************************************************************/ +bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) +{ + if (!is_ntfs_stream_smb_fname(smb_fname)) { + return false; + } + + return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0; +} diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 8bd914bf0d..a170f774fe 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -592,15 +592,6 @@ NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, return fsp_set_smb_fname(to, from->fsp_name); } -/** - * Return a debug string using the debug_ctx(). This can only be called from - * DEBUG() macros due to the debut_ctx(). - */ -const char *fsp_str_dbg(const struct files_struct *fsp) -{ - return smb_fname_str_dbg(fsp->fsp_name); -} - /** * The only way that the fsp->fsp_name field should ever be set. */ diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index a2e3ec504c..55495183bd 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -990,3 +990,58 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) } return NT_STATUS_OK; } + +/** + * XXX: This is temporary and there should be no callers of this once + * smb_filename is plumbed through all path based operations. + */ +int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf) +{ + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + int ret; + + status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + + ret = SMB_VFS_STAT(conn, smb_fname); + if (ret != -1) { + *psbuf = smb_fname->st; + } + + TALLOC_FREE(smb_fname); + return ret; +} + +/** + * XXX: This is temporary and there should be no callers of this once + * smb_filename is plumbed through all path based operations. + */ +int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf) +{ + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + int ret; + + status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + + ret = SMB_VFS_LSTAT(conn, smb_fname); + if (ret != -1) { + *psbuf = smb_fname->st; + } + + TALLOC_FREE(smb_fname); + return ret; +} + -- cgit From f4530f6d2a0688e350c3c7be23f256ebceffa636 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 15:43:21 -0700 Subject: s3: Plumb smb_filename through open_fake_file --- source3/include/proto.h | 4 ++-- source3/smbd/fake_file.c | 29 ++++++++++++++++++++++------- source3/smbd/open.c | 13 ++----------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index c26f2a7c3a..c48cebce11 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6266,11 +6266,11 @@ void reply_openerror(struct smb_request *req, NTSTATUS status); /* The following definitions come from smbd/fake_file.c */ -enum FAKE_FILE_TYPE is_fake_file(const char *fname); +enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname); NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, uint16_t current_vuid, enum FAKE_FILE_TYPE fake_file_type, - const char *fname, + const struct smb_filename *smb_fname, uint32 access_mask, files_struct **result); NTSTATUS close_fake_file(struct smb_request *req, files_struct *fsp); diff --git a/source3/smbd/fake_file.c b/source3/smbd/fake_file.c index ef54398bc4..743d88f360 100644 --- a/source3/smbd/fake_file.c +++ b/source3/smbd/fake_file.c @@ -71,23 +71,32 @@ static struct fake_file_handle *init_fake_file_handle(enum FAKE_FILE_TYPE type) Does this name match a fake filename ? ****************************************************************************/ -enum FAKE_FILE_TYPE is_fake_file(const char *fname) +enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname) { #ifdef HAVE_SYS_QUOTAS int i; + char *fname = NULL; + NTSTATUS status; #endif - if (!fname) { + if (!smb_fname) { return FAKE_FILE_TYPE_NONE; } #ifdef HAVE_SYS_QUOTAS + status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); + if (!NT_STATUS_IS_OK(status)) { + return FAKE_FILE_TYPE_NONE; + } + for (i=0;fake_files[i].name!=NULL;i++) { if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) { DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname)); + TALLOC_FREE(fname); return fake_files[i].type; } } + TALLOC_FREE(fname); #endif return FAKE_FILE_TYPE_NONE; @@ -101,7 +110,7 @@ enum FAKE_FILE_TYPE is_fake_file(const char *fname) NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, uint16_t current_vuid, enum FAKE_FILE_TYPE fake_file_type, - const char *fname, + const struct smb_filename *smb_fname, uint32 access_mask, files_struct **result) { @@ -112,7 +121,8 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, if (conn->server_info->utok.uid != 0) { DEBUG(3, ("open_fake_file_shared: access_denied to " "service[%s] file[%s] user[%s]\n", - lp_servicename(SNUM(conn)), fname, + lp_servicename(SNUM(conn)), + smb_fname_str_dbg(smb_fname), conn->server_info->unix_name)); return NT_STATUS_ACCESS_DENIED; @@ -124,7 +134,8 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, } DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n", - fname, fsp->fnum, (unsigned int)access_mask)); + smb_fname_str_dbg(smb_fname), fsp->fnum, + (unsigned int)access_mask)); fsp->conn = conn; fsp->fh->fd = -1; @@ -132,8 +143,12 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, fsp->fh->pos = -1; fsp->can_lock = False; /* Should this be true ? - No, JRA */ fsp->access_mask = access_mask; - string_set(&fsp->fsp_name,fname); - + status = fsp_set_smb_fname(fsp, smb_fname); + if (!NT_STATUS_IS_OK(status)) { + file_free(req, fsp); + return NT_STATUS_NO_MEMORY; + } + fsp->fake_file_handle = init_fake_file_handle(fake_file_type); if (fsp->fake_file_handle==NULL) { diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 33763d202d..7692c7c847 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3462,16 +3462,9 @@ NTSTATUS create_file_default(connection_struct *conn, */ if (is_ntfs_stream_smb_fname(smb_fname)) { - char *fname = NULL; enum FAKE_FILE_TYPE fake_file_type; - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } - - fake_file_type = is_fake_file(fname); + fake_file_type = is_fake_file(smb_fname); if (fake_file_type != FAKE_FILE_TYPE_NONE) { @@ -3487,9 +3480,8 @@ NTSTATUS create_file_default(connection_struct *conn, * close it */ status = open_fake_file(req, conn, req->vuid, - fake_file_type, fname, + fake_file_type, smb_fname, access_mask, &fsp); - TALLOC_FREE(fname); if (!NT_STATUS_IS_OK(status)) { goto fail; } @@ -3497,7 +3489,6 @@ NTSTATUS create_file_default(connection_struct *conn, ZERO_STRUCT(smb_fname->st); goto done; } - TALLOC_FREE(fname); if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) { status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -- cgit From 8e04c69e027260e7e1f0a4cf3e58e31ed4084d8b Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 20 Jul 2009 14:32:32 -0700 Subject: s3: Add some asserts to the filename util functions In the smb_filename struct stream_name must equal NULL if there is no stream name. These asserts should catch any future offenders of this invariant early. --- source3/smbd/filename_util.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source3/smbd/filename_util.c b/source3/smbd/filename_util.c index 1a7af714de..867709a373 100644 --- a/source3/smbd/filename_util.c +++ b/source3/smbd/filename_util.c @@ -29,6 +29,9 @@ NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, char **full_name) { if (smb_fname->stream_name) { + /* stream_name must always be NULL if there is no stream. */ + SMB_ASSERT(smb_fname->stream_name[0] != '\0'); + *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name, smb_fname->stream_name); } else { @@ -134,6 +137,10 @@ NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname_in, struct smb_filename **smb_fname_out) { + /* stream_name must always be NULL if there is no stream. */ + if (smb_fname_in->stream_name) { + SMB_ASSERT(smb_fname_in->stream_name[0] != '\0'); + } *smb_fname_out = talloc_zero(ctx, struct smb_filename); if (*smb_fname_out == NULL) { @@ -174,6 +181,11 @@ NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, ***************************************************************************/ bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) { + /* stream_name must always be NULL if there is no stream. */ + if (smb_fname->stream_name) { + SMB_ASSERT(smb_fname->stream_name[0] != '\0'); + } + if (lp_posix_pathnames()) { return false; } -- cgit From 760104188d0d2ed96ec4a70138e6d0bf86d797ed Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 21 Jul 2009 16:23:35 +0930 Subject: tdb: fix locking error 54a51839ea65aa788b18fce8de0ae4f9ba63e4e7 "Make tdb transaction lock recursive (samba version)" was broken: I "cleaned it up" and prevented it from ever unlocking. To see the problem: $ bin/tdbtorture -s 1248142523 tdb_brlock failed (fd=3) at offset 8 rw_type=1 lck_type=14 len=1 tdb_transaction_lock: failed to get transaction lock tdb_transaction_start failed: Resource deadlock avoided My testcase relied on the *count* being correct, which it was. Fixing that now. Signed-off-by: Rusty Russell Signed-off-by: Michael Adam --- lib/tdb/common/lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tdb/common/lock.c b/lib/tdb/common/lock.c index d812fbfdc5..2c72ae1f0d 100644 --- a/lib/tdb/common/lock.c +++ b/lib/tdb/common/lock.c @@ -328,7 +328,7 @@ int tdb_transaction_unlock(struct tdb_context *tdb) if (tdb->global_lock.count) { return 0; } - if (tdb->transaction_lock_count > 0) { + if (tdb->transaction_lock_count > 1) { tdb->transaction_lock_count--; return 0; } -- cgit From d5efb38151dea179af920a1a279d974a47b6bfd6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 21 Jul 2009 12:26:14 +0200 Subject: s3:dbwrap: use the transaction wrapper in dbwrap_trans_delete(). Michael --- source3/lib/dbwrap_util.c | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 7dbeb63927..32a1dd48e6 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -226,49 +226,33 @@ NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, return status; } -NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key) +static NTSTATUS dbwrap_delete_action(struct db_context * db, void *private_data) { - int res; - struct db_record *rec = NULL; NTSTATUS status; + struct db_record *rec; + TDB_DATA *key = (TDB_DATA *)private_data; - res = db->transaction_start(db); - if (res != 0) { - DEBUG(5, ("transaction_start failed\n")); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - rec = db->fetch_locked(db, talloc_tos(), key); + rec = db->fetch_locked(db, talloc_tos(), *key); if (rec == NULL) { DEBUG(5, ("fetch_locked failed\n")); - status = NT_STATUS_NO_MEMORY; - goto cancel; + return NT_STATUS_NO_MEMORY; } status = rec->delete_rec(rec); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("delete_rec returned %s\n", nt_errstr(status))); - goto cancel; } - TALLOC_FREE(rec); - - res = db->transaction_commit(db); - if (res != 0) { - DEBUG(5, ("tdb_transaction_commit failed\n")); - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - TALLOC_FREE(rec); - return status; - } + talloc_free(rec); + return status; +} - return NT_STATUS_OK; +NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key) +{ + NTSTATUS status; - cancel: - TALLOC_FREE(rec); + status = dbwrap_trans_do(db, dbwrap_delete_action, &key); - if (db->transaction_cancel(db) != 0) { - smb_panic("Cancelling transaction failed"); - } return status; } -- cgit From 319a97bce9f77161e62de9f86ddbec58629238cb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 21 Jul 2009 12:35:48 +0200 Subject: s3:dbwrap: use the transaction wrapper in dbwrap_trans_store(). Now dbwrap_util.c contains only one call to each of transaction_start, transaction_commit and transaction_cancel. Michael --- source3/lib/dbwrap_util.c | 49 ++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 32a1dd48e6..c3ab93c4df 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -179,50 +179,47 @@ int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr, return 0; } -NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, - int flag) +struct dbwrap_store_context { + TDB_DATA *key; + TDB_DATA *dbuf; + int flag; +}; + +static NTSTATUS dbwrap_store_action(struct db_context *db, void *private_data) { - int res; struct db_record *rec = NULL; NTSTATUS status; + struct dbwrap_store_context *store_ctx; - res = db->transaction_start(db); - if (res != 0) { - DEBUG(5, ("transaction_start failed\n")); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } + store_ctx = (struct dbwrap_store_context *)private_data; - rec = db->fetch_locked(db, talloc_tos(), key); + rec = db->fetch_locked(db, talloc_tos(), *(store_ctx->key)); if (rec == NULL) { DEBUG(5, ("fetch_locked failed\n")); - status = NT_STATUS_NO_MEMORY; - goto cancel; + return NT_STATUS_NO_MEMORY; } - status = rec->store(rec, dbuf, flag); + status = rec->store(rec, *(store_ctx->dbuf), store_ctx->flag); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("store returned %s\n", nt_errstr(status))); - goto cancel; } TALLOC_FREE(rec); + return status; +} - res = db->transaction_commit(db); - if (res != 0) { - DEBUG(5, ("tdb_transaction_commit failed\n")); - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - TALLOC_FREE(rec); - return status; - } +NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, + int flag) +{ + NTSTATUS status; + struct dbwrap_store_context store_ctx; - return NT_STATUS_OK; + store_ctx.key = &key; + store_ctx.dbuf = &dbuf; + store_ctx.flag = flag; - cancel: - TALLOC_FREE(rec); + status = dbwrap_trans_do(db, dbwrap_store_action, &store_ctx); - if (db->transaction_cancel(db) != 0) { - smb_panic("Cancelling transaction failed"); - } return status; } -- cgit From 8b6ec5b82cbc66cf8efd9d0713e36aac63c8c49e Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Tue, 21 Jul 2009 13:56:17 +0200 Subject: do not log chdir with level 0 if reason is access denied this changes the level of logs caused by users trying to access shares or subdirectories for which they do not have access to in the ACL this can fill up the samba log even with log level 0 and is more an expected kind of logs that IMHO should not be logged with such a high level. All other errors while chdir() will still be logged with level 0 Signed-off-by: Christian Ambach --- source3/smbd/service.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 0124b2b047..a043288bc9 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -182,8 +182,8 @@ bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir) if (do_chdir && vfs_ChDir(conn,conn->connectpath) != 0 && vfs_ChDir(conn,conn->origpath) != 0) { - DEBUG(0,("chdir (%s) failed\n", - conn->connectpath)); + DEBUG(((errno!=EACCES)?0:3),("chdir (%s) failed, reason: %s\n", + conn->connectpath, strerror(errno))); return(False); } -- cgit From 143625661300e7ee52e969bc3790e50a0016b88b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Jul 2009 16:04:07 +0200 Subject: frsapi.idl: fix some unknown field names metze --- librpc/idl/frsapi.idl | 14 +++++++------- source4/torture/rpc/frsapi.c | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/librpc/idl/frsapi.idl b/librpc/idl/frsapi.idl index 11593f479a..fd412ea1a5 100644 --- a/librpc/idl/frsapi.idl +++ b/librpc/idl/frsapi.idl @@ -98,9 +98,9 @@ interface frsapi WERROR frsapi_IsPathReplicated( [in,unique] [string,charset(UTF16)] uint16 *path, [in] frsapi_ReplicaSetType replica_set_type, - [out] uint32 *unknown1, - [out] uint32 *unknown2, - [out] uint32 *unknown3, + [out] uint32 *replicated, + [out] uint32 *primary, + [out] uint32 *root, [out] GUID *replica_set_guid ); @@ -112,10 +112,10 @@ interface frsapi /* Function 0x0a */ /* not supported before w2k3 sp2 */ WERROR frsapi_ForceReplication( - [in,unique] GUID *guid1, - [in,unique] GUID *guid2, - [in,unique] [charset(UTF16),string] uint16 *replica_set, - [in,unique] [charset(UTF16),string] uint16 *partner_name + [in,unique] GUID *replica_set_guid, + [in,unique] GUID *connection_guid, + [in,unique] [charset(UTF16),string] uint16 *replica_set_name, + [in,unique] [charset(UTF16),string] uint16 *partner_dns_name ); } diff --git a/source4/torture/rpc/frsapi.c b/source4/torture/rpc/frsapi.c index c8e421a674..e9a19bcf96 100644 --- a/source4/torture/rpc/frsapi.c +++ b/source4/torture/rpc/frsapi.c @@ -114,15 +114,15 @@ static bool test_IsPathReplicated_err(struct torture_context *tctx, { struct frsapi_IsPathReplicated r; struct GUID guid; - uint32_t unknown1, unknown2, unknown3 = 0; + uint32_t replicated, primary, root; ZERO_STRUCT(r); r.in.path = path; r.in.replica_set_type = type; - r.out.unknown1 = &unknown1; - r.out.unknown2 = &unknown2; - r.out.unknown3 = &unknown3; + r.out.replicated = &replicated; + r.out.primary = &primary; + r.out.root = &root; r.out.replica_set_guid = &guid; torture_assert_ntstatus_ok(tctx, @@ -191,11 +191,11 @@ static bool test_ForceReplication(struct torture_context *tctx, ZERO_STRUCT(r); - r.in.guid1 = NULL; - r.in.guid2 = NULL; - r.in.replica_set = talloc_asprintf(tctx, "%s", - lp_realm(tctx->lp_ctx)); - r.in.partner_name = dcerpc_server_name(p); + r.in.replica_set_guid = NULL; + r.in.connection_guid = NULL; + r.in.replica_set_name = talloc_asprintf(tctx, "%s", + lp_realm(tctx->lp_ctx)); + r.in.partner_dns_name = dcerpc_server_name(p); torture_assert_ntstatus_ok(tctx, dcerpc_frsapi_ForceReplication(p, tctx, &r), -- cgit From b91156d4ae8f1b0e60a4cdacd1aa34b110b6451a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Jul 2009 16:04:35 +0200 Subject: frsapi.idl: fill the frsapi_WriterCommand() function metze --- librpc/idl/frsapi.idl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/librpc/idl/frsapi.idl b/librpc/idl/frsapi.idl index fd412ea1a5..ea7880c9f8 100644 --- a/librpc/idl/frsapi.idl +++ b/librpc/idl/frsapi.idl @@ -106,7 +106,14 @@ interface frsapi /****************/ /* Function 0x09 */ - [todo] void FRSAPI_WRITER_COMMAND(); + typedef [v1_enum] enum { + FRSAPI_WRITER_COMMAND_FREEZE = 0x00000001, + FRSAPI_WRITER_COMMAND_THAW = 0x00000002 + } frsapi_WriterCommandsValues; + + WERROR frsapi_WriterCommand( + [in] frsapi_WriterCommandsValues command + ); /****************/ /* Function 0x0a */ -- cgit From 9d148f75c712d4cf6863f8eb1256f806eac8d38b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Jul 2009 16:05:44 +0200 Subject: frsrpc.idl: almost complete the idl for the frsrpc_FrsSendCommPkt() function TODO: The amount of chunks is dynamic, we need to fix that metze --- librpc/idl/frsrpc.idl | 399 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 312 insertions(+), 87 deletions(-) diff --git a/librpc/idl/frsrpc.idl b/librpc/idl/frsrpc.idl index 1019a25b28..54f143c1f1 100644 --- a/librpc/idl/frsrpc.idl +++ b/librpc/idl/frsrpc.idl @@ -14,112 +14,337 @@ interface frsrpc /*****************/ /* Function 0x00 */ - /* TAG:3 this TLV contains a GUID and the name of the server sending - * the call - */ typedef struct { - [subcontext(4)] GUID unknown1; - [subcontext(4)] nstring source_server; - } frsrpc_FrsSendCommPktChunkDataSSRV; + [subcontext(4)] GUID guid; + [subcontext(4)] nstring name; + } frsrpc_CommPktChunkGuidName; - /* TAG:4 this TLV contains a GUID and the name of the destination - * server the PDU is sent to - */ typedef struct { - [subcontext(4)] GUID unknown1; - [subcontext(4)] nstring dest_server; - } frsrpc_FrsSendCommPktChunkDataDSRV; + hyper vsn; + GUID guid; + } frsrpc_CommPktGSVN; + + typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap { + FRSRPC_CO_FLAG_ABORT_CO = 0x00000001, + FRSRPC_CO_FLAG_VV_ACTIVATED = 0x00000002, + FRSRPC_CO_FLAG_CONTENT_CMD = 0x00000004, + FRSRPC_CO_FLAG_LOCATION_CMD = 0x00000008, + FRSRPC_CO_FLAG_ONLIST = 0x00000010, + FRSRPC_CO_FLAG_LOCALCO = 0x00000020, + FRSRPC_CO_FLAG_RETRY = 0x00000040, + FRSRPC_CO_FLAG_OUT_OF_ORDER = 0x00000200, + FRSRPC_CO_FLAG_NEW_FILE = 0x00000400, + FRSRPC_CO_FLAG_CONTROL = 0x00001000, + FRSRPC_CO_FLAG_DIRECTED_CO = 0x00002000, + FRSRPC_CO_FLAG_VVJOIN_TO_ORIG = 0x00040000, + FRSRPC_CO_FLAG_SKIP_ORIG_REC_C = 0x00100000, + FRSRPC_CO_FLAG_MOVEIN_GEN = 0x00200000, + FRSRPC_CO_FLAG_MORPH_GEN_HEAD = 0x00400000, + FRSRPC_CO_FLAG_JUST_OID_RESET = 0x00800000, + FRSRPC_CO_FLAG_COMPRESSED_STAGE = 0x01000000, + FRSRPC_CO_FLAG_COMPRESSED_STAGE = 0x01000000, + FRSRPC_CO_FLAG_SKIP_VV_UPDATE = 0x02000000 + } frsrpc_CommPktCoCmdFlags; + + const uint32 FRSRPC_CO_IFLAG_NONE = 0x0000000; + + typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap { + FRSRPC_CO_IFLAG_VVRETIRE_EXEC = 0x00000001, + FRSRPC_CO_IFLAG_CO_ABORT = 0x00000002, + FRSRPC_CO_IFLAG_DIR_ENUM_PENDING= 0x00000004 + } frsrpc_CommPktCoCmdIFlags; + + typedef [v1_enum,flag(NDR_PAHEX)] enum { + FRSRPC_CO_STATUS_CO_ENTERED_LOG = 0x00000000, + FRSRPC_CO_STATUS_ALLOC_STAGING_LOCAL_CO = 0x00000001, + FRSRPC_CO_STATUS_LOCAL_CO_STAGING_STARTED = 0x00000002, + FRSRPC_CO_STATUS_LOCAL_CO_STAGING_COMPLETED = 0x00000003, + FRSRPC_CO_STATUS_WAIT_RETRY_LOCAL_CO_STAGING = 0x00000004, + FRSRPC_CO_STATUS_ALLOC_STAGING_REMOTE_CO = 0x00000005, + FRSRPC_CO_STATUS_REMOTE_CO_STAGING_STARTED = 0x00000006, + FRSRPC_CO_STATUS_REMOTE_CO_STAGING_COMPLETED = 0x00000007, + FRSRPC_CO_STATUS_WAIT_RETRY_REMOTE_CO_STAGING = 0x00000008, + FRSRPC_CO_STATUS_FILE_INSTALL_REQUESTED = 0x00000009, + FRSRPC_CO_STATUS_FILE_INSTALL_STARTED = 0x0000000A, + FRSRPC_CO_STATUS_FILE_INSTALL_COMPLETED = 0x0000000B, + FRSRPC_CO_STATUS_FILE_INSTALL_WAIT_RETRY = 0x0000000C, + FRSRPC_CO_STATUS_FILE_INSTALL_RETRYING = 0x0000000D, + FRSRPC_CO_STATUS_FILE_INSTALL_RENAME_RETRYING = 0x0000000E, + FRSRPC_CO_STATUS_FILE_INSTALL_DELETE_RETRYING = 0x0000000F, + FRSRPC_CO_STATUS_CO_RECYCLED_FOR_ENUM = 0x00000013, + FRSRPC_CO_STATUS_REQUEST_OUTBOUND_PROPAGATION = 0x00000014, + FRSRPC_CO_STATUS_REQUEST_ACCEPTED_OUTBOUND_LOG = 0x00000015, + FRSRPC_CO_STATUS_DB_STATE_UPDATE_STARTED = 0x00000016, + FRSRPC_CO_STATUS_DB_STATE_UPDATE_COMPLETED = 0x00000017, + FRSRPC_CO_STATUS_CO_ABORTED = 0x00000018 + } frsrpc_CommPktCoCmdStatus; + + typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap { + FRSRPC_CONTENT_REASON_DATA_OVERWRITE = 0x00000001, + FRSRPC_CONTENT_REASON_DATA_EXTEND = 0x00000002, + FRSRPC_CONTENT_REASON_DATA_TRUNCATION = 0x00000004, + FRSRPC_CONTENT_REASON_NAMED_DATA_OVERWRITE = 0x00000010, + FRSRPC_CONTENT_REASON_NAMED_DATA_EXTEND = 0x00000020, + FRSRPC_CONTENT_REASON_NAMED_DATA_TRUNCATION = 0x00000040, + FRSRPC_CONTENT_REASON_FILE_CREATE = 0x00000100, + FRSRPC_CONTENT_REASON_FILE_DELETE = 0x00000200, + FRSRPC_CONTENT_REASON_EA_CHANGE = 0x00000400, + FRSRPC_CONTENT_REASON_SECURITY_CHANGE = 0x00000800, + FRSRPC_CONTENT_REASON_OLD_NAME = 0x00001000, + FRSRPC_CONTENT_REASON_NEW_NAME = 0x00002000, + FRSRPC_CONTENT_REASON_BASIC_INFO_CHANGE = 0x00004000, + FRSRPC_CONTENT_REASON_COMPRESSION_CHANGE = 0x00020000 + } frsrpc_CommPktCoCmdContentCmd; + + typedef [v1_enum,flag(NDR_PAHEX)] enum { + FRSRPC_CO_LOCATION_FILE_CREATE = 0x00000000, + FRSRPC_CO_LOCATION_DIR_CREATE = 0x00000000 | 0x00000001, + FRSRPC_CO_LOCATION_FILE_DELETE = 0x00000002, + FRSRPC_CO_LOCATION_DIR_DELETE = 0x00000002 | 0x00000001, + FRSRPC_CO_LOCATION_FILE_MOVEIN = 0x00000004, + FRSRPC_CO_LOCATION_DIR_MOVEIN = 0x00000004 | 0x00000001, + FRSRPC_CO_LOCATION_FILE_MOVEIN2 = 0x00000006, + FRSRPC_CO_LOCATION_DIR_MOVEIN2 = 0x00000006 | 0x00000001, + FRSRPC_CO_LOCATION_FILE_MOVEOUT = 0x00000008, + FRSRPC_CO_LOCATION_DIR_MOVEOUT = 0x00000008 | 0x00000001, + FRSRPC_CO_LOCATION_FILE_MOVERS = 0x0000000a, + FRSRPC_CO_LOCATION_DIR_MOVERS = 0x0000000a | 0x00000001, + FRSRPC_CO_LOCATION_FILE_MOVEDIR = 0x0000000c, + FRSRPC_CO_LOCATION_DIR_MOVEDIR = 0x0000000c | 0x00000001, + FRSRPC_CO_LOCATION_FILE_NO_CMD = 0x0000000e, + FRSRPC_CO_LOCATION_DIR_NO_CMD = 0x0000000e | 0x00000001 + } frsrpc_CommPktCoCmdLocationCmd; - /* TAG:18 this TLV contains a timestamp - */ typedef struct { - [subcontext(4)] NTTIME time; - } frsrpc_FrsSendCommPktChunkDataTS; + uint32 sequence_number; + frsrpc_CommPktCoCmdFlags flags; + frsrpc_CommPktCoCmdIFlags iflags; + frsrpc_CommPktCoCmdStatus status; + frsrpc_CommPktCoCmdContentCmd content_cmd; + frsrpc_CommPktCoCmdLocationCmd location_cmd; + uint32 file_attributes; + uint32 file_version_number; + uint32 partern_ack_sequence_number; + [value(0)] uint32 not_used; + hyper file_size; + hyper file_offset; + hyper frs_vsn; + hyper file_usn; + hyper jrnl_usn; + hyper jrnl_first_usn; + uint32 original_replica_num; + uint32 new_replica_num; + GUID change_order_guid; + GUID originator_guid; + GUID file_guid; + GUID old_parent_guid; + GUID new_parent_guid; + GUID connection_guid; + hyper ack_version; + [value(0)] hyper spare2ul1; + [value(0)] hyper spare1guid_p1; + [value(0)] hyper spare1guid_p2; + [value(0)] hyper spare2guid_p1; + [value(0)] hyper spare3guid_p2; + [value(0)] uint32 spare1wcs; + [value(0)] uint32 spare2wcs; + [value(0)] uint32 extension; + [value(0)] uint32 spare2bin; + NTTIME event_time; + [value(2*strlen_m(file_name))] uint16 file_name_length; +#define FRSRPC_MAX_PATH 260 + [charset(UTF16)] uint16 file_name[FRSRPC_MAX_PATH+1]; + [value(0)] uint8 padding1; + [value(0)] uint8 padding2; + [value(0)] uint8 padding3; + [value(0)] uint8 padding4; + } frsrpc_CommPktChangeOrderCommand; + + typedef [v1_enum,flag(NDR_PAHEX)] enum { + FRSRPC_DATA_EXTENSION_TERMINATOR = 0x00000000, + FRSRPC_DATA_EXTENSION_MD5_CHECKSUM = 0x00000001, + FRSRPC_DATA_EXTENSION_RETRY_TIMEOUT = 0x00000002 + } frsrpc_CommPktDataExtensionType; + typedef [flag(NDR_PAHEX)] struct { + [value(0x00000018)] uint32 prefix_size; + [value(FRSRPC_DATA_EXTENSION_MD5_CHECKSUM)] + frsrpc_CommPktDataExtensionType prefix_type; + uint8 data[16]; + } frsrpc_CommPktDataExtensionChecksum; typedef struct { - uint32 unknown1; - } frsrpc_FrsSendCommPktChunkDataA; + [value(0x00000018)] uint32 prefix_size; + [value(FRSRPC_DATA_EXTENSION_RETRY_TIMEOUT)] + frsrpc_CommPktDataExtensionType prefix_type; + uint32 count; + [value(0)] uint32 not_used; + NTTIME first_try_time; + } frsrpc_CommPktDataExtensionRetryTimeout; + + typedef [flag(NDR_PAHEX)] enum { + FRSRPC_CO_RECORD_EXTENSION_VERSION_WIN2K = 0x0000, + FRSRPC_CO_RECORD_EXTENSION_VERSION_1 = 0x0001 + } frsrpc_CommPktCoRecordExtensionMajor; typedef struct { - uint32 unknown1; - GUID unknown2; - [subcontext(4)] nstring unknown3; - } frsrpc_FrsSendCommPktChunkDataB; + [value(0x00000028)] uint32 field_size; + [value(FRSRPC_CO_RECORD_EXTENSION_VERSION_WIN2K)] + frsrpc_CommPktCoRecordExtensionMajor major; + [value(0x0001)] uint16 offset_count; + [value(0x00000010)] uint32 offset; + [value(0)] uint32 offset_last; + frsrpc_CommPktDataExtensionChecksum data_checksum; + } frsrpc_CommPktCoRecordExtensionWin2k; typedef struct { - uint32 unknown1; - GUID unknown2; - } frsrpc_FrsSendCommPktChunkDataC; + [value(0x00000048)] uint32 field_size; + frsrpc_CommPktCoRecordExtensionMajor major; + [value(0x0002)] uint16 offset_count; + [value(0x00000018)] uint32 offset0; + [value(0x00000030)] uint32 offset1;/*TODO: is this correct??? */ + [value(0)] uint32 offset_last; + [value(0)] uint32 not_used; + frsrpc_CommPktDataExtensionChecksum data_checksum; + frsrpc_CommPktDataExtensionRetryTimeout data_retry_timeout; + } frsrpc_CommPktChangeOrderRecordExtension; + + typedef [v1_enum,flag(NDR_PAHEX)] enum { + FRSRPC_COMMAND_REMOTE_CO = 0x00000218, + FRSRPC_COMMAND_RECEIVING_STATE = 0x00000238, + FRSRPC_COMMAND_REMOTE_CO_DONE = 0x00000250, + FRSRPC_COMMAND_ABORT_FETCH = 0x00000246, + FRSRPC_COMMAND_RETRY_FETCH = 0x00000244, + FRSRPC_COMMAND_NEED_JOIN = 0x00000121, + FRSRPC_COMMAND_START_JOIN = 0x00000122, + FRSRPC_COMMAND_JOINING = 0x00000130, + FRSRPC_COMMAND_JOINED = 0x00000128, + FRSRPC_COMMAND_UNJOIN_REMOTE = 0x00000148, + FRSRPC_COMMAND_WJOIN_DONE = 0x00000136, + FRSRPC_COMMAND_SEND_STAGE = 0x00000228 + } frsrpc_CommPktCommand; + + typedef [flag(NDR_PAHEX)] enum { + FRSRPC_COMM_PKT_CHUNK_BOP = 0x0001, + FRSRPC_COMM_PKT_CHUNK_COMMAND = 0x0002, + FRSRPC_COMM_PKT_CHUNK_TO = 0x0003, + FRSRPC_COMM_PKT_CHUNK_FROM = 0x0004, + FRSRPC_COMM_PKT_CHUNK_REPLICA = 0x0005, + FRSRPC_COMM_PKT_CHUNK_CONNECTION = 0x0008, + FRSRPC_COMM_PKT_CHUNK_JOIN_GUID = 0x0006, + FRSRPC_COMM_PKT_CHUNK_LAST_JOIN_TIME = 0x0012, + + FRSRPC_COMM_PKT_CHUNK_VVECTOR = 0x0007, + FRSRPC_COMM_PKT_CHUNK_JOIN_TIME = 0x0011, + FRSRPC_COMM_PKT_CHUNK_REPLICA_VERSION_GUID = 0x0014, + FRSRPC_COMM_PKT_CHUNK_COMPRESSION_GUID = 0x0018, + + FRSRPC_COMM_PKT_CHUNK_BLOCK = 0x0009, + FRSRPC_COMM_PKT_CHUNK_BLOCK_SIZE = 0x000A, + FRSRPC_COMM_PKT_CHUNK_FILE_SIZE = 0x000B, + FRSRPC_COMM_PKT_CHUNK_FILE_OFFSET = 0x000C, + FRSRPC_COMM_PKT_CHUNK_GVSN = 0x000E, + FRSRPC_COMM_PKT_CHUNK_CO_GUID = 0x000F, + FRSRPC_COMM_PKT_CHUNK_CO_SEQUENCE_NUMBER = 0x0010, + + FRSRPC_COMM_PKT_CHUNK_REMOTE_CO = 0x000D, + FRSRPC_COMM_PKT_CHUNK_CO_EXT_WIN2K = 0x0016, + FRSRPC_COMM_PKT_CHUNK_CO_EXTENTION_2 = 0x0017, + + FRSRPC_COMM_PKT_CHUNK_EOP = 0x0013 + } frsrpc_CommPktChunkType; typedef [nodiscriminant] union { [default,flag(NDR_REMAINING)] DATA_BLOB blob; - [case(1)] frsrpc_FrsSendCommPktChunkDataA A; - [case(2)] frsrpc_FrsSendCommPktChunkDataA A; - [case(3)] frsrpc_FrsSendCommPktChunkDataSSRV SSRV; - [case(4)] frsrpc_FrsSendCommPktChunkDataDSRV DSRV; - [case(5)] frsrpc_FrsSendCommPktChunkDataB B; - [case(8)] frsrpc_FrsSendCommPktChunkDataB B; - [case(6)] frsrpc_FrsSendCommPktChunkDataC C; - [case(18)] frsrpc_FrsSendCommPktChunkDataTS TS; - [case(19)] frsrpc_FrsSendCommPktChunkDataA A; - } frsrpc_FrsSendCommPktChunkData; - - typedef struct { - uint16 type; - [subcontext(4),switch_is(type)] frsrpc_FrsSendCommPktChunkData data; - } frsrpc_FrsSendCommPktChunk; + [case(FRSRPC_COMM_PKT_CHUNK_BOP)] + [value(0)] uint32 bop; + [case(FRSRPC_COMM_PKT_CHUNK_COMMAND)] + frsrpc_CommPktCommand command; + [case(FRSRPC_COMM_PKT_CHUNK_TO)] + frsrpc_CommPktChunkGuidName to; + [case(FRSRPC_COMM_PKT_CHUNK_FROM)] + frsrpc_CommPktChunkGuidName from; + [case(FRSRPC_COMM_PKT_CHUNK_REPLICA)] + frsrpc_CommPktChunkGuidName replica; + [case(FRSRPC_COMM_PKT_CHUNK_CONNECTION)] + frsrpc_CommPktChunkGuidName connection; + [case(FRSRPC_COMM_PKT_CHUNK_JOIN_GUID)][subcontext(4)] + GUID join_guid; + [case(FRSRPC_COMM_PKT_CHUNK_LAST_JOIN_TIME)] + NTTIME last_join_time; + [case(FRSRPC_COMM_PKT_CHUNK_VVECTOR)][subcontext(4)] + frsrpc_CommPktGSVN vvector; + [case(FRSRPC_COMM_PKT_CHUNK_JOIN_TIME)][subcontext(4)] + NTTIME join_time; + [case(FRSRPC_COMM_PKT_CHUNK_REPLICA_VERSION_GUID)][subcontext(4)] + GUID replica_version_guid; + [case(FRSRPC_COMM_PKT_CHUNK_COMPRESSION_GUID)] + GUID compression_guid; + [case(FRSRPC_COMM_PKT_CHUNK_BLOCK)] + [flag(NDR_REMAINING)] DATA_BLOB block; + [case(FRSRPC_COMM_PKT_CHUNK_BLOCK_SIZE)] + hyper block_size; + [case(FRSRPC_COMM_PKT_CHUNK_FILE_SIZE)] + hyper file_size; + [case(FRSRPC_COMM_PKT_CHUNK_FILE_OFFSET)] + hyper file_offset; + [case(FRSRPC_COMM_PKT_CHUNK_GVSN)][subcontext(4)] + frsrpc_CommPktGSVN gvsn; + [case(FRSRPC_COMM_PKT_CHUNK_CO_GUID)][subcontext(4)] + GUID co_guid; + [case(FRSRPC_COMM_PKT_CHUNK_CO_SEQUENCE_NUMBER)] + uint32 co_sequnence_number; + [case(FRSRPC_COMM_PKT_CHUNK_REMOTE_CO)][subcontext(4)] + frsrpc_CommPktChangeOrderCommand remote_co; + [case(FRSRPC_COMM_PKT_CHUNK_CO_EXT_WIN2K)][subcontext(4)] + frsrpc_CommPktCoRecordExtensionWin2k co_ext_win2k; + [case(FRSRPC_COMM_PKT_CHUNK_CO_EXTENTION_2)][subcontext(4)] + frsrpc_CommPktChangeOrderRecordExtension co_extension2; + [case(FRSRPC_COMM_PKT_CHUNK_EOP)] + [value(0xFFFFFFFF)] uint32 bop; + } frsrpc_CommPktChunkData; typedef [flag(NDR_NOALIGN)] struct { - frsrpc_FrsSendCommPktChunk chunk1; - frsrpc_FrsSendCommPktChunk chunk2; - frsrpc_FrsSendCommPktChunk chunk3; - frsrpc_FrsSendCommPktChunk chunk4; - frsrpc_FrsSendCommPktChunk chunk5; - frsrpc_FrsSendCommPktChunk chunk6; - frsrpc_FrsSendCommPktChunk chunk7; - frsrpc_FrsSendCommPktChunk chunk8; - frsrpc_FrsSendCommPktChunk chunk9; - } frsrpc_FrsSendCommPktChunkCtr; + frsrpc_CommPktChunkType type; + [subcontext(4),switch_is(type)] frsrpc_CommPktChunkData data; + } frsrpc_CommPktChunk; + + typedef [gensize,flag(NDR_NOALIGN)] struct { + /* TODO: make this dynamic */ + frsrpc_CommPktChunk chunks[9]; + } frsrpc_CommPktChunkCtr; + + typedef [v1_enum] enum { + FRSRPC_COMM_PKT_MAJOR_0 = 0x00000000 + } frsrpc_CommPktMajor; + + typedef [v1_enum] enum { + FRSRPC_COMM_PKT_MINOR_0 = 0x00000000, + FRSRPC_COMM_PKT_MINOR_1 = 0x00000001, + FRSRPC_COMM_PKT_MINOR_2 = 0x00000002, + FRSRPC_COMM_PKT_MINOR_3 = 0x00000003, + FRSRPC_COMM_PKT_MINOR_4 = 0x00000004, + FRSRPC_COMM_PKT_MINOR_5 = 0x00000005, + FRSRPC_COMM_PKT_MINOR_6 = 0x00000006, + FRSRPC_COMM_PKT_MINOR_7 = 0x00000007, + FRSRPC_COMM_PKT_MINOR_8 = 0x00000008, + FRSRPC_COMM_PKT_MINOR_9 = 0x00000009 + } frsrpc_CommPktMinor; typedef struct { - uint32 unknown1; - uint32 unknown2; - uint32 unknown3; - uint32 unknown4; - uint32 tlv_size; - uint32 unknown6; - uint32 unknown7; /* This may be a UNIQUE pointer? */ - uint32 unknown8; - uint32 unknown9; - /* - * The format of this blob is this a concatenation - * of TLVs which are not really NDR encoded. - * - * The individual TLVs are encoded as : - * struct { - * uint16 type; - * [subcontext(4),switch_is(type)] chunk_data data; - * } chunk; - * - * some of the chunk are like this: - * - * struct { - * uint32 unknown; // 0x00000010 - * struct GUID guid; - * lstring string; - * } ...; - * - * - * The tags are (might be) : - * 3: Source server sending the PDU - * 4: Destination server the PDU is sent to - * 18: Timestamp - * - */ - [subcontext(4)/*,size_is(tlv_size)*/] frsrpc_FrsSendCommPktChunkCtr *chunks; - uint32 unknown10; - uint32 unknown11; + frsrpc_CommPktMajor major; + frsrpc_CommPktMinor minor; + [value(1)] uint32 cs_id; + [value(pkt_len+12)] uint32 memory_len; + [value(ndr_size_frsrpc_CommPktChunkCtr(r->ctr, + ndr->iconv_convenience, ndr->flags))] + [range(0, 262144)] + uint32 pkt_len; + [value(0)] uint32 upk_len; + [subcontext(4),subcontext_size(pkt_len)] + frsrpc_CommPktChunkCtr *ctr; + [value(0)] uint32 data_name; + [value(0)] uint32 data_handle; } frsrpc_FrsSendCommPktReq; WERROR frsrpc_FrsSendCommPkt( -- cgit From 424e7636957f07c044ee24a9bbf650b02291939b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Jul 2009 16:48:06 +0200 Subject: frsrpc.idl: make the chunk array in frsrpc_CommPktChunkCtr dynamic We add an extra num_chunks to the frsrpc_CommPktChunkCtr structure and use hand modified ndr_push/pull functions to let it not appear on the wire. metze --- librpc/idl/frsrpc.idl | 9 ++--- librpc/ndr/ndr_frsrpc.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ librpc/ndr/ndr_frsrpc.h | 35 ++++++++++++++++++ source4/librpc/config.mk | 2 +- 4 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 librpc/ndr/ndr_frsrpc.c create mode 100644 librpc/ndr/ndr_frsrpc.h diff --git a/librpc/idl/frsrpc.idl b/librpc/idl/frsrpc.idl index 54f143c1f1..233fbcb174 100644 --- a/librpc/idl/frsrpc.idl +++ b/librpc/idl/frsrpc.idl @@ -7,6 +7,7 @@ import "misc.idl"; version(1.1), endpoint("ncacn_ip_tcp:", "ncalrpc:"), helpstring("File Replication Service"), + helper("../librpc/ndr/ndr_frsrpc.h"), pointer_default(unique) ] interface frsrpc @@ -304,14 +305,14 @@ interface frsrpc [value(0xFFFFFFFF)] uint32 bop; } frsrpc_CommPktChunkData; - typedef [flag(NDR_NOALIGN)] struct { + typedef [public,flag(NDR_NOALIGN)] struct { frsrpc_CommPktChunkType type; [subcontext(4),switch_is(type)] frsrpc_CommPktChunkData data; } frsrpc_CommPktChunk; - typedef [gensize,flag(NDR_NOALIGN)] struct { - /* TODO: make this dynamic */ - frsrpc_CommPktChunk chunks[9]; + typedef [nopull,nopush,flag(NDR_NOALIGN)] struct { + uint32 num_chunks; /* this doesn't appear on the wire */ + frsrpc_CommPktChunk chunks[num_chunks]; } frsrpc_CommPktChunkCtr; typedef [v1_enum] enum { diff --git a/librpc/ndr/ndr_frsrpc.c b/librpc/ndr/ndr_frsrpc.c new file mode 100644 index 0000000000..c99745999c --- /dev/null +++ b/librpc/ndr/ndr_frsrpc.c @@ -0,0 +1,94 @@ +/* + Unix SMB/CIFS implementation. + + helper routines for FRSRPC marshalling + + Copyright (C) Stefan (metze) Metzmacher 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 . +*/ + +#include "replace.h" +#include "librpc/gen_ndr/ndr_frsrpc.h" + +enum ndr_err_code ndr_push_frsrpc_CommPktChunkCtr(struct ndr_push *ndr, + int ndr_flags, + const struct frsrpc_CommPktChunkCtr *r) +{ + uint32_t cntr_chunks_0; + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 2)); + for (cntr_chunks_0 = 0; cntr_chunks_0 < r->num_chunks; cntr_chunks_0++) { + NDR_CHECK(ndr_push_frsrpc_CommPktChunk(ndr, NDR_SCALARS, &r->chunks[cntr_chunks_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} + +#define _TMP_PULL_REALLOC_N(ndr, s, t, n) do { \ + _NDR_PULL_FIX_CURRENT_MEM_CTX(ndr);\ + (s) = talloc_realloc(ndr->current_mem_ctx, (s), t, n); \ + if (!(s)) { \ + return ndr_pull_error(ndr, NDR_ERR_ALLOC, \ + "Alloc %u * %s failed: %s\n", \ + (unsigned)n, # s, __location__); \ + } \ +} while (0) + +enum ndr_err_code ndr_pull_frsrpc_CommPktChunkCtr(struct ndr_pull *ndr, + int ndr_flags, + struct frsrpc_CommPktChunkCtr *r) +{ + uint32_t cntr_chunks_0; + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + uint32_t remaining = ndr->data_size - ndr->offset; + r->num_chunks = 0; + r->chunks = NULL; + for (cntr_chunks_0 = 0; remaining > 0; cntr_chunks_0++) { + r->num_chunks += 1; + _TMP_PULL_REALLOC_N(ndr, r->chunks, + struct frsrpc_CommPktChunk, + r->num_chunks); + NDR_CHECK(ndr_pull_frsrpc_CommPktChunk(ndr, + NDR_SCALARS, + &r->chunks[cntr_chunks_0])); + remaining = ndr->data_size - ndr->offset; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} + +size_t ndr_size_frsrpc_CommPktChunkCtr(const struct frsrpc_CommPktChunkCtr *r, + struct smb_iconv_convenience *ic, + int flags) +{ + flags |= LIBNDR_FLAG_NOALIGN; + return ndr_size_struct(r, flags, + (ndr_push_flags_fn_t)ndr_push_frsrpc_CommPktChunkCtr, + ic); +} diff --git a/librpc/ndr/ndr_frsrpc.h b/librpc/ndr/ndr_frsrpc.h new file mode 100644 index 0000000000..e8dc76959b --- /dev/null +++ b/librpc/ndr/ndr_frsrpc.h @@ -0,0 +1,35 @@ +/* + Unix SMB/CIFS implementation. + + helper routines for FRSRPC marshalling + + Copyright (C) Stefan (metze) Metzmacher 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 . +*/ + +#ifndef _LIBRPC_NDR_NDR_FRSRPC_H +#define _LIBRPC_NDR_NDR_FRSRPC_H + +enum ndr_err_code ndr_push_frsrpc_CommPktChunkCtr(struct ndr_push *ndr, + int ndr_flags, + const struct frsrpc_CommPktChunkCtr *r); +enum ndr_err_code ndr_pull_frsrpc_CommPktChunkCtr(struct ndr_pull *ndr, + int ndr_flags, + struct frsrpc_CommPktChunkCtr *r); +size_t ndr_size_frsrpc_CommPktChunkCtr(const struct frsrpc_CommPktChunkCtr *r, + struct smb_iconv_convenience *ic, + int flags); + +#endif /* _LIBRPC_NDR_NDR_FRSRPC_H */ diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 9e3d6b27ea..e96cf2c516 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -112,7 +112,7 @@ NDR_ROT_OBJ_FILES = ../librpc/gen_ndr/ndr_rot.o [SUBSYSTEM::NDR_FRSRPC] PUBLIC_DEPENDENCIES = LIBNDR -NDR_FRSRPC_OBJ_FILES = ../librpc/gen_ndr/ndr_frsrpc.o +NDR_FRSRPC_OBJ_FILES = ../librpc/gen_ndr/ndr_frsrpc.o ../librpc/ndr/ndr_frsrpc.o [SUBSYSTEM::NDR_FRSAPI] PUBLIC_DEPENDENCIES = LIBNDR -- cgit From 6b49f28592af5c998642bd5d5f76b77c79a22cd7 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 09:29:59 -0700 Subject: s3: Plumb smb_filename through map_open_params_to_ntcreate --- source3/include/proto.h | 3 ++- source3/smbd/open.c | 10 ++++++---- source3/smbd/reply.c | 19 ++++++++++--------- source3/smbd/trans2.c | 10 ++++------ 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index c48cebce11..fe81bd2c97 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6589,7 +6589,8 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, uint32 access_mask, uint32 share_access, uint32 create_options); -bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func, +bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname, + int deny_mode, int open_func, uint32 *paccess_mask, uint32 *pshare_mode, uint32 *pcreate_disposition, diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 7692c7c847..87cab1966b 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1199,7 +1199,8 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, Open a file with a share mode - old openX method - map into NTCreate. ****************************************************************************/ -bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func, +bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname, + int deny_mode, int open_func, uint32 *paccess_mask, uint32 *pshare_mode, uint32 *pcreate_disposition, @@ -1212,7 +1213,8 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, " "open_func = 0x%x\n", - fname, (unsigned int)deny_mode, (unsigned int)open_func )); + smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode, + (unsigned int)open_func )); /* Create the NT compatible access_mask. */ switch (GET_OPENX_MODE(deny_mode)) { @@ -1286,7 +1288,7 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func case DENY_DOS: create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS; - if (is_executable(fname)) { + if (is_executable(smb_fname->base_name)) { share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; } else { if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) { @@ -1311,7 +1313,7 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, " "share_mode = 0x%x, create_disposition = 0x%x, " "create_options = 0x%x\n", - fname, + smb_fname_str_dbg(smb_fname), (unsigned int)access_mask, (unsigned int)share_mode, (unsigned int)create_disposition, diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 46fdd4adde..5924c46cc1 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1760,10 +1760,10 @@ void reply_open(struct smb_request *req) goto out; } - if (!map_open_params_to_ntcreate( - smb_fname->base_name, deny_mode, OPENX_FILE_EXISTS_OPEN, - &access_mask, &share_mode, &create_disposition, - &create_options)) { + if (!map_open_params_to_ntcreate(smb_fname, deny_mode, + OPENX_FILE_EXISTS_OPEN, &access_mask, + &share_mode, &create_disposition, + &create_options)) { reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess)); goto out; } @@ -1931,9 +1931,10 @@ void reply_open_and_X(struct smb_request *req) goto out; } - if (!map_open_params_to_ntcreate( - smb_fname->base_name, deny_mode, smb_ofun, &access_mask, - &share_mode, &create_disposition, &create_options)) { + if (!map_open_params_to_ntcreate(smb_fname, deny_mode, smb_ofun, + &access_mask, &share_mode, + &create_disposition, + &create_options)) { reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess)); goto out; } @@ -6659,8 +6660,8 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, if (!target_is_directory && count) { new_create_disposition = FILE_OPEN; } else { - if (!map_open_params_to_ntcreate(smb_fname_dst_tmp->base_name, - 0, ofun, NULL, NULL, + if (!map_open_params_to_ntcreate(smb_fname_dst_tmp, 0, ofun, + NULL, NULL, &new_create_disposition, NULL)) { status = NT_STATUS_INVALID_PARAMETER; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index e2efed331d..9ce541aa63 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1046,12 +1046,10 @@ static void call_trans2open(connection_struct *conn, goto out; } - if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode, - open_ofun, - &access_mask, - &share_mode, - &create_disposition, - &create_options)) { + if (!map_open_params_to_ntcreate(smb_fname, deny_mode, open_ofun, + &access_mask, &share_mode, + &create_disposition, + &create_options)) { reply_doserror(req, ERRDOS, ERRbadaccess); goto out; } -- cgit From 78ce9dd471568773760292ea18478af51c11d71a Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 10:18:10 -0700 Subject: s3: Remove unnecessary fname argument from callers of filename_convert --- source3/smbd/trans2.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 9ce541aa63..2f1f50b11d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4748,7 +4748,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn, uint16 info_level; unsigned int data_size = 0; unsigned int param_size = 2; - char *fname = NULL; struct smb_filename *smb_fname = NULL; bool delete_pending = False; struct timespec write_time_ts; @@ -4861,6 +4860,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, } } else { + char *fname = NULL; + /* qpathinfo */ if (total_params < 7) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -4889,7 +4890,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, &smb_fname, - &fname); + NULL); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -4969,7 +4970,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, } else if (!VALID_STAT(smb_fname->st) && SMB_VFS_STAT(conn, smb_fname) && (info_level != SMB_INFO_IS_NAME_VALID)) { - ms_dfs_link = check_msdfs_link(conn, fname, + ms_dfs_link = check_msdfs_link(conn, + smb_fname->base_name, &smb_fname->st); if (!ms_dfs_link) { @@ -4991,8 +4993,9 @@ static void call_trans2qfilepathinfo(connection_struct *conn, } } - DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n", - fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data)); + DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d " + "total_data=%d\n", smb_fname_str_dbg(smb_fname), + fsp ? fsp->fnum : -1, info_level,tran_call,total_data)); /* Pull out any data sent here before we realloc. */ switch (info_level) { @@ -7348,7 +7351,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn, char *params = *pparams; char *pdata = *ppdata; uint16 info_level; - char *fname = NULL; struct smb_filename *smb_fname = NULL; files_struct *fsp = NULL; NTSTATUS status = NT_STATUS_OK; @@ -7443,6 +7445,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } } } else { + char *fname = NULL; + /* set path info */ if (total_params < 7) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -7462,7 +7466,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, &smb_fname, - &fname); + NULL); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -7493,8 +7497,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } } - DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n", - tran_call, fname, fsp ? fsp->fnum : -1, info_level,total_data)); + DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d " + "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname), + fsp ? fsp->fnum : -1, info_level,total_data)); /* Realloc the parameter size */ *pparams = (char *)SMB_REALLOC(*pparams,2); -- cgit From 4860fc4951a7dbd80d8938f4dba49c42a12b4d00 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 10:19:00 -0700 Subject: s3: Fix RENAME_FLAG_RENAME path to stop calling unix_convert twice --- source3/smbd/nttrans.c | 125 +++++++++++++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 50 deletions(-) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index ecb88296ca..af79986df4 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1317,8 +1317,7 @@ void reply_ntrename(struct smb_request *req) if (req->wct < 4) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - END_PROFILE(SMBntrename); - return; + goto out; } attrs = SVAL(req->vwv+0, 0); @@ -1329,14 +1328,12 @@ void reply_ntrename(struct smb_request *req) &status, &src_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); - END_PROFILE(SMBntrename); - return; + goto out; } if (ms_has_wild(oldname)) { reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD); - END_PROFILE(SMBntrename); - return; + goto out; } p++; @@ -1344,55 +1341,85 @@ void reply_ntrename(struct smb_request *req) &status, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); - END_PROFILE(SMBntrename); - return; + goto out; } - status = filename_convert(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - oldname, - &smb_fname_old, - &oldname); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, - ERRSRV, ERRbadpath); - END_PROFILE(SMBntrename); - return; - } - reply_nterror(req, status); - END_PROFILE(SMBntrename); - return; + /* The newname must begin with a ':' if the oldname contains a ':'. */ + if (strchr_m(oldname, ':') && (newname[0] != ':')) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + goto out; } - status = filename_convert(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - newname, - &smb_fname_new, - &newname); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, - ERRSRV, ERRbadpath); - END_PROFILE(SMBntrename); - return; + /* rename_internals() calls unix_convert(), so don't call it here. */ + if (rename_type != RENAME_FLAG_RENAME) { + status = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + oldname, + &smb_fname_old, + NULL); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); + goto out; } - reply_nterror(req, status); - END_PROFILE(SMBntrename); - return; - } - /* The new name must begin with a ':' if the old name is a stream. */ - if (is_ntfs_stream_smb_fname(smb_fname_old) && (newname[0] != ':')) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - END_PROFILE(SMBntrename); - return; - } + status = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + newname, + &smb_fname_new, + NULL); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); + goto out; + } - DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname)); + DEBUG(3,("reply_ntrename: %s -> %s\n", + smb_fname_str_dbg(smb_fname_old), + smb_fname_str_dbg(smb_fname_new))); + } switch(rename_type) { case RENAME_FLAG_RENAME: + status = resolve_dfspath(ctx, conn, + (req->flags2 & + FLAGS2_DFS_PATHNAMES), + oldname, &oldname); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("resolve_dfspath failed for name %s " + "with %s\n", oldname, + nt_errstr(status))); + reply_nterror(req, status); + goto out; + } + + status = resolve_dfspath(ctx, conn, + (req->flags2 & + FLAGS2_DFS_PATHNAMES), + newname, &newname); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("resolve_dfspath failed for name %s " + "with %s\n", newname, + nt_errstr(status))); + reply_nterror(req, status); + goto out; + } + + DEBUG(3,("reply_ntrename: %s -> %s\n", oldname, + newname)); + status = rename_internals(ctx, conn, req, oldname, newname, attrs, False, src_has_wcard, dest_has_wcard, DELETE_ACCESS); @@ -1430,17 +1457,15 @@ void reply_ntrename(struct smb_request *req) if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { /* We have re-scheduled this call. */ - END_PROFILE(SMBntrename); - return; + goto out; } reply_nterror(req, status); - END_PROFILE(SMBntrename); - return; + goto out; } reply_outbuf(req, 0, 0); - + out: END_PROFILE(SMBntrename); return; } -- cgit From 00e267008defe18475115a4300addf3cbcabff5a Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 10:28:28 -0700 Subject: s3: Remove the now unused fname parameter from filename_convert() --- source3/include/proto.h | 3 +-- source3/rpc_server/srv_srvsvc_nt.c | 6 ++---- source3/smbd/filename.c | 16 ++++------------ source3/smbd/nttrans.c | 12 ++++-------- source3/smbd/reply.c | 27 +++++++++------------------ source3/smbd/smb2_create.c | 3 +-- source3/smbd/trans2.c | 15 +++++---------- 7 files changed, 26 insertions(+), 56 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index fe81bd2c97..77283d9cf0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6320,8 +6320,7 @@ NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, connection_struct *conn, bool dfs_path, const char *name_in, - struct smb_filename **pp_smb_fname, - char **pp_name); + struct smb_filename **pp_smb_fname); /* The following definitions come from smbd/filename_utils.c */ diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index c58c08ecdc..b9d1ed6d73 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -2072,8 +2072,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, conn, false, r->in.file, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); goto error_exit; @@ -2201,8 +2200,7 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, conn, false, r->in.file, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); goto error_exit; diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index c05f0e659f..541b0cd3cb 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1018,8 +1018,7 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, connection_struct *conn, bool dfs_path, const char *name_in, - struct smb_filename **pp_smb_fname, - char **pp_name) + struct smb_filename **pp_smb_fname) { NTSTATUS status; char *fname = NULL; @@ -1046,22 +1045,15 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, return status; } - status = get_full_smb_filename(ctx, *pp_smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = check_name(conn, fname); + status = check_name(conn, (*pp_smb_fname)->base_name); if (!NT_STATUS_IS_OK(status)) { DEBUG(3,("filename_convert: check_name failed " "for name %s with %s\n", - fname, + smb_fname_str_dbg(*pp_smb_fname), nt_errstr(status) )); + TALLOC_FREE(*pp_smb_fname); return status; } - if (pp_name != NULL) { - *pp_name = fname; - } return status; } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index af79986df4..43212dc800 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -478,8 +478,7 @@ void reply_ntcreate_and_X(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -968,8 +967,7 @@ static void call_nt_transact_create(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1355,8 +1353,7 @@ void reply_ntrename(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, oldname, - &smb_fname_old, - NULL); + &smb_fname_old); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_PATH_NOT_COVERED)) { @@ -1372,8 +1369,7 @@ void reply_ntrename(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, newname, - &smb_fname_new, - NULL); + &smb_fname_new); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_PATH_NOT_COVERED)) { diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 5924c46cc1..72595aeda7 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -994,8 +994,7 @@ void reply_checkpath(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, name, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1091,8 +1090,7 @@ void reply_getatr(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -1193,8 +1191,7 @@ void reply_setatr(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -1747,8 +1744,7 @@ void reply_open(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -1918,8 +1914,7 @@ void reply_open_and_X(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -2128,8 +2123,7 @@ void reply_mknew(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -2261,8 +2255,7 @@ void reply_ctemp(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -5267,8 +5260,7 @@ void reply_mkdir(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, - &smb_dname, - NULL); + &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -5575,8 +5567,7 @@ void reply_rmdir(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, - &smb_dname, - NULL); + &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 7337a345fd..b455f82d80 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -325,8 +325,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, smbreq->conn, smbreq->flags2 & FLAGS2_DFS_PATHNAMES, in_name, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); TALLOC_FREE(smb_fname); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 2f1f50b11d..8637d1bda1 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1028,8 +1028,7 @@ static void call_trans2open(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -4889,8 +4888,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -5664,8 +5662,7 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, oldname, - &smb_fname_old, - NULL); + &smb_fname_old); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -7465,8 +7462,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, status = filename_convert(req, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -7587,8 +7583,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, - &smb_dname, - NULL); + &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { -- cgit From 23c703a01eddfa9103352e0ad43bc9fe39ea0c27 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 11:35:17 -0700 Subject: s3: Remove unnecessary callers of get_full_smb_filename This often times means explicitly denying certain operations on a stream as they are not supported or don't make sense at a particular level. At some point in the future these can be enabled, but for now it's better to remove ambiguity --- source3/modules/vfs_default.c | 58 +++++++++-------------------- source3/smbd/close.c | 5 +-- source3/smbd/file_access.c | 10 +---- source3/smbd/reply.c | 86 ++++++++++++++----------------------------- source3/smbd/trans2.c | 81 +++++++++++++++++----------------------- 5 files changed, 81 insertions(+), 159 deletions(-) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index d6a66b01de..cdfd28c571 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -218,27 +218,17 @@ static int vfswrap_open(vfs_handle_struct *handle, struct smb_filename *smb_fname, files_struct *fsp, int flags, mode_t mode) { - int result; - NTSTATUS status; - char *fname = NULL; + int result = -1; START_PROFILE(syscall_open); - /* - * XXX: Should an error be returned if there is a stream rather than - * trying to open a filename with a ':'? - */ - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; } - result = sys_open(fname, flags, mode); - - TALLOC_FREE(fname); - + result = sys_open(smb_fname->base_name, flags, mode); + out: END_PROFILE(syscall_open); return result; } @@ -562,23 +552,17 @@ static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp) static int vfswrap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { - int result; - NTSTATUS status; - char *fname = NULL; + int result = -1; START_PROFILE(syscall_stat); - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; } - result = sys_stat(fname, &smb_fname->st); - - TALLOC_FREE(fname); - + result = sys_stat(smb_fname->base_name, &smb_fname->st); + out: END_PROFILE(syscall_stat); return result; } @@ -596,23 +580,17 @@ static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUC static int vfswrap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { - int result; - NTSTATUS status; - char *fname = NULL; + int result = -1; START_PROFILE(syscall_lstat); - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; } - result = sys_lstat(fname, &smb_fname->st); - - TALLOC_FREE(fname); - + result = sys_lstat(smb_fname->base_name, &smb_fname->st); + out: END_PROFILE(syscall_lstat); return result; } diff --git a/source3/smbd/close.c b/source3/smbd/close.c index f878aaa056..788b0a7cec 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -47,10 +47,7 @@ static NTSTATUS check_magic(struct files_struct *fsp) ctx = talloc_stackframe(); - status = get_full_smb_filename(ctx, fsp->fsp_name, &fname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } + fname = fsp->fsp_name->base_name; if (!(p = strrchr_m(fname,'/'))) { p = fname; diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index d8fee1db06..7d0a552956 100644 --- a/source3/smbd/file_access.c +++ b/source3/smbd/file_access.c @@ -33,7 +33,6 @@ bool can_access_file_acl(struct connection_struct *conn, NTSTATUS status; uint32_t access_granted; struct security_descriptor *secdesc = NULL; - char *fname = NULL; bool ret; if (conn->server_info->utok.uid == 0 || conn->admin_user) { @@ -41,13 +40,7 @@ bool can_access_file_acl(struct connection_struct *conn, return true; } - status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - ret = false; - goto out; - } - - status = SMB_VFS_GET_NT_ACL(conn, fname, + status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION), @@ -62,7 +55,6 @@ bool can_access_file_acl(struct connection_struct *conn, access_mask, &access_granted); ret = NT_STATUS_IS_OK(status); out: - TALLOC_FREE(fname); TALLOC_FREE(secdesc); return ret; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 72595aeda7..76d32a2f98 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1340,6 +1340,7 @@ void reply_search(struct smb_request *req) char *path = NULL; const char *mask = NULL; char *directory = NULL; + struct smb_filename *smb_fname = NULL; char *fname = NULL; SMB_OFF_T size; uint32 mode; @@ -1364,14 +1365,12 @@ void reply_search(struct smb_request *req) if (req->wct < 2) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - END_PROFILE(SMBsearch); - return; + goto out; } if (lp_posix_pathnames()) { reply_unknown_new(req, req->cmd); - END_PROFILE(SMBsearch); - return; + goto out; } /* If we were called as SMBffirst then we must expect close. */ @@ -1387,8 +1386,7 @@ void reply_search(struct smb_request *req) &nt_status, &mask_contains_wcard); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } p++; @@ -1398,8 +1396,6 @@ void reply_search(struct smb_request *req) /* dirtype &= ~aDIR; */ if (status_len == 0) { - struct smb_filename *smb_fname = NULL; - nt_status = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, path, @@ -1409,35 +1405,25 @@ void reply_search(struct smb_request *req) if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); - END_PROFILE(SMBsearch); - return; + goto out; } reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } nt_status = unix_convert(ctx, conn, path, &smb_fname, UCF_ALLOW_WCARD_LCOMP); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } - nt_status = get_full_smb_filename(ctx, smb_fname, &directory); - TALLOC_FREE(smb_fname); - if (!NT_STATUS_IS_OK(nt_status)) { - reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; - } + directory = smb_fname->base_name; nt_status = check_name(conn, directory); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } p = strrchr_m(directory,'/'); @@ -1452,8 +1438,7 @@ void reply_search(struct smb_request *req) if (!directory) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } memset((char *)status,'\0',21); @@ -1470,8 +1455,7 @@ void reply_search(struct smb_request *req) &conn->dirptr); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } dptr_num = dptr_dnum(conn->dirptr); } else { @@ -1511,8 +1495,7 @@ void reply_search(struct smb_request *req) if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)), 0,aVOLID,0,!allow_long_path_components)) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } dptr_fill(buf+12,dptr_num); if (dptr_zero(buf+12) && (status_len==0)) { @@ -1524,8 +1507,7 @@ void reply_search(struct smb_request *req) data_blob_const(buf, sizeof(buf))) == -1) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } } else { unsigned int i; @@ -1564,8 +1546,7 @@ void reply_search(struct smb_request *req) convert_timespec_to_time_t(date), !allow_long_path_components)) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } if (!dptr_fill(buf+12,dptr_num)) { break; @@ -1574,8 +1555,7 @@ void reply_search(struct smb_request *req) data_blob_const(buf, sizeof(buf))) == -1) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } numentries++; } @@ -1602,8 +1582,7 @@ void reply_search(struct smb_request *req) if ((numentries == 0) && !mask_contains_wcard) { reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles); - END_PROFILE(SMBsearch); - return; + goto out; } SSVAL(req->outbuf,smb_vwv0,numentries); @@ -1635,7 +1614,8 @@ void reply_search(struct smb_request *req) dirtype, numentries, maxentries )); - + out: + TALLOC_FREE(smb_fname); END_PROFILE(SMBsearch); return; } @@ -5811,9 +5791,6 @@ static void notify_rename(connection_struct *conn, bool is_dir, { char *parent_dir_src = NULL; char *parent_dir_dst = NULL; - char *fname_src = NULL; - char *fname_dst = NULL; - NTSTATUS status; uint32 mask; mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME @@ -5826,24 +5803,17 @@ static void notify_rename(connection_struct *conn, bool is_dir, goto out; } - status = get_full_smb_filename(talloc_tos(), smb_fname_src, - &fname_src); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - status = get_full_smb_filename(talloc_tos(), smb_fname_dst, - &fname_dst); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - if (strcmp(parent_dir_src, parent_dir_dst) == 0) { - notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, fname_src); - notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, fname_dst); + notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, + smb_fname_src->base_name); + notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, + smb_fname_dst->base_name); } else { - notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, fname_src); - notify_fname(conn, NOTIFY_ACTION_ADDED, mask, fname_dst); + notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, + smb_fname_src->base_name); + notify_fname(conn, NOTIFY_ACTION_ADDED, mask, + smb_fname_dst->base_name); } /* this is a strange one. w2k3 gives an additional event for @@ -5853,13 +5823,11 @@ static void notify_rename(connection_struct *conn, bool is_dir, notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES |FILE_NOTIFY_CHANGE_CREATION, - fname_dst); + smb_fname_dst->base_name); } out: TALLOC_FREE(parent_dir_src); TALLOC_FREE(parent_dir_dst); - TALLOC_FREE(fname_src); - TALLOC_FREE(fname_dst); } /**************************************************************************** diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 8637d1bda1..daaf97c18d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -471,17 +471,13 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const struct smb_filename *smb_fname, struct ea_list *ea_list) { char *fname = NULL; - NTSTATUS status; if (!lp_ea_support(SNUM(conn))) { return NT_STATUS_EAS_NOT_SUPPORTED; } - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + /* For now setting EAs on streams isn't supported. */ + fname = smb_fname->base_name; for (;ea_list; ea_list = ea_list->next) { int ret; @@ -2039,7 +2035,7 @@ static void call_trans2findfirst(connection_struct *conn, if (total_params < 13) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } dirtype = SVAL(params,0); @@ -2077,12 +2073,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", ask_sharemode = false; if (!lp_unix_extensions()) { reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + goto out; } break; default: reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + goto out; } srvstr_get_path_wcard(ctx, params, req->flags2, &directory, @@ -2090,7 +2086,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", STR_TERMINATE, &ntstatus, &mask_contains_wcard); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } ntstatus = resolve_dfspath_wcard(ctx, conn, @@ -2102,32 +2098,27 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); - return; + goto out; } reply_nterror(req, ntstatus); - return; + goto out; } ntstatus = unix_convert(ctx, conn, directory, &smb_dname, (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP)); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } mask = smb_dname->original_lcomp; - ntstatus = get_full_smb_filename(ctx, smb_dname, &directory); - TALLOC_FREE(smb_dname); - if (!NT_STATUS_IS_OK(ntstatus)) { - reply_nterror(req, ntstatus); - return; - } + directory = smb_dname->base_name; ntstatus = check_name(conn, directory); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } p = strrchr_m(directory,'/'); @@ -2137,14 +2128,14 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", mask = talloc_strdup(ctx,"*"); if (!mask) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } mask_contains_wcard = True; } directory = talloc_strdup(talloc_tos(), "./"); if (!directory) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } } else { *p = 0; @@ -2157,7 +2148,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", if (total_data < 4) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } ea_size = IVAL(pdata,0); @@ -2165,19 +2156,19 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) )); reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } if (!lp_ea_support(SNUM(conn))) { reply_doserror(req, ERRDOS, ERReasnotsupported); - return; + goto out; } /* Pull out the list of names. */ ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4); if (!ea_list) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } } @@ -2185,7 +2176,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); if(*ppdata == NULL ) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } pdata = *ppdata; data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; @@ -2194,7 +2185,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd *pparams = (char *)SMB_REALLOC(*pparams, 10); if (*pparams == NULL) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } params = *pparams; @@ -2213,7 +2204,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } dptr_num = dptr_dnum(conn->dirptr); @@ -2296,11 +2287,11 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd dptr_close(&dptr_num); if (Protocol < PROTOCOL_NT1) { reply_doserror(req, ERRDOS, ERRnofiles); - return; + goto out; } else { reply_botherror(req, NT_STATUS_NO_SUCH_FILE, ERRDOS, ERRbadfile); - return; + goto out; } } @@ -2339,7 +2330,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd char mangled_name[13]; name_to_8_3(mask, mangled_name, True, conn->params); } - + out: + TALLOC_FREE(smb_dname); return; } @@ -5122,8 +5114,6 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, const struct smb_filename *smb_fname_old, const struct smb_filename *smb_fname_new) { - char *oldname = NULL; - char *newname = NULL; NTSTATUS status = NT_STATUS_OK; /* source must already exist. */ @@ -5141,25 +5131,22 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, return NT_STATUS_FILE_IS_A_DIRECTORY; } - status = get_full_smb_filename(ctx, smb_fname_new, &newname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - status = get_full_smb_filename(ctx, smb_fname_old, &oldname); - if (!NT_STATUS_IS_OK(status)) { - goto out; + /* Setting a hardlink to/from a stream isn't currently supported. */ + if (is_ntfs_stream_smb_fname(smb_fname_old) || + is_ntfs_stream_smb_fname(smb_fname_new)) { + return NT_STATUS_INVALID_PARAMETER; } - DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname )); + DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", + smb_fname_old->base_name, smb_fname_new->base_name)); - if (SMB_VFS_LINK(conn,oldname,newname) != 0) { + if (SMB_VFS_LINK(conn, smb_fname_old->base_name, + smb_fname_new->base_name) != 0) { status = map_nt_error_from_unix(errno); DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n", - nt_errstr(status), newname, oldname)); + nt_errstr(status), smb_fname_old->base_name, + smb_fname_new->base_name)); } - out: - TALLOC_FREE(newname); - TALLOC_FREE(oldname); return status; } -- cgit From 605649edc3d3ce4f760b08fd8ee5684007369be8 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 11:37:51 -0700 Subject: s3: plumb smb_filename through some of the trans2 posix_* functions --- source3/smbd/trans2.c | 98 ++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 60 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index daaf97c18d..cac0147c4d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3994,7 +3994,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, } DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n", - fname, fsp ? fsp->fnum : -1, info_level, max_data_bytes)); + smb_fname_str_dbg(smb_fname), fsp ? fsp->fnum : -1, + info_level, max_data_bytes)); if (ms_dfs_link) { mode = dos_mode_msdfs(conn, smb_fname); @@ -5546,10 +5547,10 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn, struct smb_request *req, const char *pdata, int total_data, - const char *fname) + const struct smb_filename *smb_fname) { char *link_target = NULL; - const char *newname = fname; + const char *newname = smb_fname->base_name; NTSTATUS status = NT_STATUS_OK; TALLOC_CTX *ctx = talloc_tos(); @@ -5825,8 +5826,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, - const char *fname, - SMB_STRUCT_STAT *psbuf) + const struct smb_filename *smb_fname) { uint16 posix_acl_version; uint16 num_file_acls; @@ -5861,18 +5861,20 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, } DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n", - fname ? fname : fsp_str_dbg(fsp), + smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp), (unsigned int)num_file_acls, (unsigned int)num_def_acls)); - if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls, - pdata + SMB_POSIX_ACL_HEADER_SIZE)) { + if (valid_file_acls && !set_unix_posix_acl(conn, fsp, + smb_fname->base_name, num_file_acls, + pdata + SMB_POSIX_ACL_HEADER_SIZE)) { return map_nt_error_from_unix(errno); } - if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, psbuf, num_def_acls, - pdata + SMB_POSIX_ACL_HEADER_SIZE + - (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) { + if (valid_def_acls && !set_unix_posix_default_acl(conn, + smb_fname->base_name, &smb_fname->st, num_def_acls, + pdata + SMB_POSIX_ACL_HEADER_SIZE + + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) { return map_nt_error_from_unix(errno); } return NT_STATUS_OK; @@ -6640,11 +6642,9 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, struct smb_request *req, char **ppdata, int total_data, - const char *fname, - SMB_STRUCT_STAT *psbuf, + struct smb_filename *smb_fname, int *pdata_return_size) { - struct smb_filename *smb_fname; NTSTATUS status = NT_STATUS_OK; uint32 raw_unixmode = 0; uint32 mod_unixmode = 0; @@ -6661,7 +6661,8 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, raw_unixmode = IVAL(pdata,8); /* Next 4 bytes are not yet defined. */ - status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_DIR, &unixmode); + status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode, + PERM_NEW_DIR, &unixmode); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -6669,13 +6670,7 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS; DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n", - fname, (unsigned int)unixmode )); - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + smb_fname_str_dbg(smb_fname), (unsigned int)unixmode)); status = SMB_VFS_CREATE_FILE( conn, /* conn */ @@ -6694,9 +6689,6 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, &fsp, /* result */ &info); /* pinfo */ - *psbuf = smb_fname->st; - TALLOC_FREE(smb_fname); - if (NT_STATUS_IS_OK(status)) { close_file(req, fsp, NORMAL_CLOSE); } @@ -6727,12 +6719,14 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, case SMB_QUERY_FILE_UNIX_BASIC: SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC); SSVAL(pdata,10,0); /* Padding. */ - store_file_unix_basic(conn, pdata + 12, fsp, psbuf); + store_file_unix_basic(conn, pdata + 12, fsp, + &smb_fname->st); break; case SMB_QUERY_FILE_UNIX_INFO2: SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2); SSVAL(pdata,10,0); /* Padding. */ - store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf); + store_file_unix_basic_info2(conn, pdata + 12, fsp, + &smb_fname->st); break; default: SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED); @@ -6751,11 +6745,9 @@ static NTSTATUS smb_posix_open(connection_struct *conn, struct smb_request *req, char **ppdata, int total_data, - const char *fname, - SMB_STRUCT_STAT *psbuf, + struct smb_filename *smb_fname, int *pdata_return_size) { - struct smb_filename *smb_fname = NULL; bool extended_oplock_granted = False; char *pdata = *ppdata; uint32 flags = 0; @@ -6788,8 +6780,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn, return smb_posix_mkdir(conn, req, ppdata, total_data, - fname, - psbuf, + smb_fname, pdata_return_size); } @@ -6828,11 +6819,10 @@ static NTSTATUS smb_posix_open(connection_struct *conn, raw_unixmode = IVAL(pdata,8); /* Next 4 bytes are not yet defined. */ - status = unix_perms_from_wire(conn, - psbuf, - raw_unixmode, - VALID_STAT(*psbuf) ? PERM_EXISTING_FILE : PERM_NEW_FILE, - &unixmode); + status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode, + (VALID_STAT(smb_fname->st) ? + PERM_EXISTING_FILE : PERM_NEW_FILE), + &unixmode); if (!NT_STATUS_IS_OK(status)) { return status; @@ -6851,16 +6841,10 @@ static NTSTATUS smb_posix_open(connection_struct *conn, } DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n", - fname, + smb_fname_str_dbg(smb_fname), (unsigned int)wire_open_mode, (unsigned int)unixmode )); - status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -6879,9 +6863,6 @@ static NTSTATUS smb_posix_open(connection_struct *conn, &fsp, /* result */ &info); /* pinfo */ - *psbuf = smb_fname->st; - TALLOC_FREE(smb_fname); - if (!NT_STATUS_IS_OK(status)) { return status; } @@ -6934,12 +6915,14 @@ static NTSTATUS smb_posix_open(connection_struct *conn, case SMB_QUERY_FILE_UNIX_BASIC: SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC); SSVAL(pdata,10,0); /* padding. */ - store_file_unix_basic(conn, pdata + 12, fsp, psbuf); + store_file_unix_basic(conn, pdata + 12, fsp, + &smb_fname->st); break; case SMB_QUERY_FILE_UNIX_INFO2: SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2); SSVAL(pdata,10,0); /* padding. */ - store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf); + store_file_unix_basic_info2(conn, pdata + 12, fsp, + &smb_fname->st); break; default: SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED); @@ -7073,16 +7056,12 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, int *ret_data_size) { char *pdata = *ppdata; - SMB_STRUCT_STAT sbuf; char *fname = NULL; NTSTATUS status = NT_STATUS_OK; int data_return_size = 0; *ret_data_size = 0; - /* Set sbuf for use below. */ - sbuf = smb_fname->st; - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { return NT_STATUS_INVALID_LEVEL; } @@ -7100,8 +7079,9 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, return status; } - DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d totdata=%d\n", - fname, fsp ? fsp->fnum : -1, info_level, total_data)); + DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d " + "totdata=%d\n", smb_fname_str_dbg(smb_fname), + fsp ? fsp->fnum : -1, info_level, total_data)); switch (info_level) { @@ -7232,7 +7212,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, return NT_STATUS_INVALID_LEVEL; } status = smb_set_file_unix_link(conn, req, pdata, - total_data, fname); + total_data, smb_fname); break; } @@ -7263,8 +7243,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, pdata, total_data, fsp, - fname, - &sbuf); + smb_fname); break; } #endif @@ -7289,8 +7268,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, status = smb_posix_open(conn, req, ppdata, total_data, - fname, - &sbuf, + smb_fname, &data_return_size); break; } -- cgit From 1887ad0a26cca026c3503f0ef4e40f8eff42a121 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 22 Jul 2009 18:04:58 +1000 Subject: s4:provision Fix provision on FreeBSD We were missing the 'cn' attribute, which we then prepare a sorted list based on. On Linux, strcmp(NULL, NULL) does not segfault, where it does on FreeBSD. Reported by Timur I. Bakeyev Andrew Bartlett --- source4/scripting/python/samba/ms_schema.py | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/scripting/python/samba/ms_schema.py b/source4/scripting/python/samba/ms_schema.py index 2e8050e503..a0abc337ce 100644 --- a/source4/scripting/python/samba/ms_schema.py +++ b/source4/scripting/python/samba/ms_schema.py @@ -226,6 +226,7 @@ def __transform_entry(entry, objectClass): assert(cn) entry.insert(0, ["dn", "CN=%s,${SCHEMADN}" % cn]) entry.insert(1, ["objectClass", ["top", objectClass]]) + entry.insert(2, ["cn", cn]) for l in entry: key = l[0].lower() -- cgit From 8f5ef1063354b4ce32dfc9122e8221e2fea88890 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sun, 5 Jul 2009 09:21:07 +0200 Subject: Revert "net: Use samba default command line arguments." This reverts commit fb262f79fab00374023e59476e8d05a1015a7041 and related commits c36031778e1983ddb11d3e1fcab35e738dbf94bc 72fd5fa6bb78a054fad5e5ebe19a0c0387a7d45b and 38cd0e086f50ce54d88a19aa5a6803469af90489 This change caused more trouble than it solved. We need to do this differently. Reverting so we don't accidently release this. --- WHATSNEW.txt | 35 ------------- source3/utils/net.c | 43 ++++++++++++---- source3/utils/net.h | 9 +++- source3/utils/net_ads.c | 83 +++++++++++++++--------------- source3/utils/net_dom.c | 8 ++- source3/utils/net_help.c | 1 - source3/utils/net_proto.h | 3 ++ source3/utils/net_rpc.c | 74 +++++++++------------------ source3/utils/net_rpc_join.c | 3 +- source3/utils/net_rpc_samsync.c | 4 +- source3/utils/net_rpc_shell.c | 9 ++-- source3/utils/net_util.c | 109 +++++++++++++++++++++++++++++++++------- 12 files changed, 209 insertions(+), 172 deletions(-) diff --git a/WHATSNEW.txt b/WHATSNEW.txt index fe8d541de8..066f718999 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -14,9 +14,6 @@ Authentication Changes: o Changed the way smbd handles untrusted domain names given during user authentication -net Command Changes: -o parameter syntax made more consistent - Authentication Changes ====================== @@ -35,38 +32,6 @@ on smbd to always pass through bogus names to the DC for verification. A new parameter "map untrusted to domain" can be enabled to revert to the legacy behavior. -net Command Changes -=================== - -The net command now accepts the common command line parameters most other Samba -command line utilities use, with a couple of remaining differences: - --l still gives long output for net commands supporting the --long flag. This was -more useful than the common --log-base parameter. - --i still tells net to read data from stdin (like --stdin) instead of toggling -the common --scope flag. - --S still tells net the server to connect to (like --server) instead of -negotiating the common --signing flag. As -S is probably used by most scripts -doing net rpc commands, this would have been a high-impact change for little -gain. - -This change was mainly done to unify the authentification options. Here, one -flag changed it's meaning and one useful flag was added. - --N used to be the short version of --ntname. It now matches the Samba default of ---no-pass. Use this to stop net from prompting for a password if you want -anonymous authentication. - --A --authentication-file now takes an authentication file with the username and -password you want net to use, avoiding a password prompt as with plain -U user -or having to give a password on the command line as in -U user%pass. - -Last but not least net now always falls back to your local unix username if no --U is specified and a username is needed. net rpc commands will now prompt for a -password unless one is specified using either -U user%pass or -A auth_file. - ###################################################################### Reporting bugs & Development Discussion ####################################### diff --git a/source3/utils/net.c b/source3/utils/net.c index 9f29ac42fe..f8bfab3e99 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -625,6 +625,7 @@ static struct functable net_func[] = { int main(int argc, const char **argv) { int opt,i; + char *p; int rc = 0; int argc_new = 0; const char ** argv_new; @@ -635,10 +636,12 @@ static struct functable net_func[] = { struct poptOption long_options[] = { {"help", 'h', POPT_ARG_NONE, 0, 'h'}, {"workgroup", 'w', POPT_ARG_STRING, &c->opt_target_workgroup}, + {"user", 'U', POPT_ARG_STRING, &c->opt_user_name, 'U'}, {"ipaddress", 'I', POPT_ARG_STRING, 0,'I'}, {"port", 'p', POPT_ARG_INT, &c->opt_port}, {"myname", 'n', POPT_ARG_STRING, &c->opt_requester_name}, {"server", 'S', POPT_ARG_STRING, &c->opt_host}, + {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" }, {"container", 'c', POPT_ARG_STRING, &c->opt_container}, {"comment", 'C', POPT_ARG_STRING, &c->opt_comment}, {"maxusers", 'M', POPT_ARG_INT, &c->opt_maxusers}, @@ -649,13 +652,15 @@ static struct functable net_func[] = { {"stdin", 'i', POPT_ARG_NONE, &c->opt_stdin}, {"timeout", 't', POPT_ARG_INT, &c->opt_timeout}, {"request-timeout",0,POPT_ARG_INT, &c->opt_request_timeout}, + {"machine-pass",'P', POPT_ARG_NONE, &c->opt_machine_pass}, + {"kerberos", 'k', POPT_ARG_NONE, &c->opt_kerberos}, {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup}, {"verbose", 'v', POPT_ARG_NONE, &c->opt_verbose}, {"test", 'T', POPT_ARG_NONE, &c->opt_testmode}, /* Options for 'net groupmap set' */ {"local", 'L', POPT_ARG_NONE, &c->opt_localgroup}, {"domain", 'D', POPT_ARG_NONE, &c->opt_domaingroup}, - {"ntname", 0, POPT_ARG_STRING, &c->opt_newntname}, + {"ntname", 'N', POPT_ARG_STRING, &c->opt_newntname}, {"rid", 'R', POPT_ARG_INT, &c->opt_rid}, /* Options for 'net rpc share migrate' */ {"acls", 0, POPT_ARG_NONE, &c->opt_acls}, @@ -670,7 +675,6 @@ static struct functable net_func[] = { {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries}, POPT_COMMON_SAMBA - POPT_COMMON_CREDENTIALS { 0, 0, 0, 0} }; @@ -684,13 +688,6 @@ static struct functable net_func[] = { dbf = x_stderr; c->private_data = net_func; - c->auth_info = user_auth_info_init(frame); - if (c->auth_info == NULL) { - d_fprintf(stderr, "\nOut of memory!\n"); - exit(1); - } - popt_common_set_auth_info(c->auth_info); - pc = poptGetContext(NULL, argc, (const char **) argv, long_options, POPT_CONTEXT_KEEP_FIRST); @@ -698,7 +695,9 @@ static struct functable net_func[] = { switch (opt) { case 'h': c->display_usage = true; - set_cmdline_auth_info_password(c->auth_info, ""); + break; + case 'e': + c->smb_encrypt = true; break; case 'I': if (!interpret_string_addr(&c->opt_dest_ip, @@ -708,6 +707,15 @@ static struct functable net_func[] = { c->opt_have_ip = true; } break; + case 'U': + c->opt_user_specified = true; + c->opt_user_name = SMB_STRDUP(c->opt_user_name); + p = strchr(c->opt_user_name,'%'); + if (p) { + *p = 0; + c->opt_password = p+1; + } + break; default: d_fprintf(stderr, "\nInvalid option %s: %s\n", poptBadOption(pc, 0), poptStrerror(opt)); @@ -741,6 +749,10 @@ static struct functable net_func[] = { set_global_myname(c->opt_requester_name); } + if (!c->opt_user_name && getenv("LOGNAME")) { + c->opt_user_name = getenv("LOGNAME"); + } + if (!c->opt_workgroup) { c->opt_workgroup = smb_xstrdup(lp_workgroup()); } @@ -758,6 +770,17 @@ static struct functable net_func[] = { that it won't assert becouse we are not root */ sec_init(); + if (c->opt_machine_pass) { + /* it is very useful to be able to make ads queries as the + machine account for testing purposes and for domain leave */ + + net_use_krb_machine_account(c); + } + + if (!c->opt_password) { + c->opt_password = getenv("PASSWD"); + } + rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func); DEBUG(2,("return code = %d\n", rc)); diff --git a/source3/utils/net.h b/source3/utils/net.h index f604d96361..d88f962d41 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -28,8 +28,11 @@ struct net_context { const char *opt_requester_name; const char *opt_host; - int opt_long_list_entries; + const char *opt_password; + const char *opt_user_name; + bool opt_user_specified; const char *opt_workgroup; + int opt_long_list_entries; int opt_reboot; int opt_force; int opt_stdin; @@ -42,6 +45,7 @@ struct net_context { int opt_timeout; int opt_request_timeout; const char *opt_target_workgroup; + int opt_machine_pass; int opt_localgroup; int opt_domaingroup; int do_talloc_report; @@ -53,14 +57,15 @@ struct net_context { const char *opt_exclude; const char *opt_destination; int opt_testmode; + bool opt_kerberos; int opt_force_full_repl; int opt_single_obj_repl; int opt_clean_old_entries; int opt_have_ip; struct sockaddr_storage opt_dest_ip; + bool smb_encrypt; struct libnetapi_ctx *netapi_ctx; - struct user_auth_info *auth_info; bool display_usage; void *private_data; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index f746fc6bd5..8f76c0eb09 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -231,23 +231,32 @@ retry_connect: ads = ads_init(realm, c->opt_target_workgroup, c->opt_host); + if (!c->opt_user_name) { + c->opt_user_name = "administrator"; + } + + if (c->opt_user_specified) { + need_password = true; + } + retry: - if (need_password) { - set_cmdline_auth_info_getpass(c->auth_info); + if (!c->opt_password && need_password && !c->opt_machine_pass) { + c->opt_password = net_prompt_pass(c, c->opt_user_name); + if (!c->opt_password) { + ads_destroy(&ads); + return ADS_ERROR(LDAP_NO_MEMORY); + } } - if (get_cmdline_auth_info_got_pass(c->auth_info) || - !get_cmdline_auth_info_use_kerberos(c->auth_info)) { + if (c->opt_password) { use_in_memory_ccache(); SAFE_FREE(ads->auth.password); - ads->auth.password = smb_xstrdup( - get_cmdline_auth_info_password(c->auth_info)); + ads->auth.password = smb_xstrdup(c->opt_password); } ads->auth.flags |= auth_flags; SAFE_FREE(ads->auth.user_name); - ads->auth.user_name = smb_xstrdup( - get_cmdline_auth_info_username(c->auth_info)); + ads->auth.user_name = smb_xstrdup(c->opt_user_name); /* * If the username is of the form "name@realm", @@ -866,7 +875,6 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv) TALLOC_CTX *ctx; struct libnet_UnjoinCtx *r = NULL; WERROR werr; - struct user_auth_info *ai = c->auth_info; if (c->display_usage) { d_printf("Usage:\n" @@ -885,7 +893,7 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv) return -1; } - if (!get_cmdline_auth_info_use_kerberos(ai)) { + if (!c->opt_kerberos) { use_in_memory_ccache(); } @@ -895,14 +903,12 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv) return -1; } - set_cmdline_auth_info_getpass(ai); - r->in.debug = true; - r->in.use_kerberos = get_cmdline_auth_info_use_kerberos(ai); + r->in.use_kerberos = c->opt_kerberos; r->in.dc_name = c->opt_host; r->in.domain_name = lp_realm(); - r->in.admin_account = get_cmdline_auth_info_username(ai); - r->in.admin_password = get_cmdline_auth_info_password(ai); + r->in.admin_account = c->opt_user_name; + r->in.admin_password = net_prompt_pass(c, c->opt_user_name); r->in.modify_config = lp_config_backend_is_registry(); /* Try to delete it, but if that fails, disable it. The @@ -960,8 +966,7 @@ static NTSTATUS net_ads_join_ok(struct net_context *c) return NT_STATUS_ACCESS_DENIED; } - set_cmdline_auth_info_use_machine_account(c->auth_info); - set_cmdline_auth_info_machine_account_creds(c->auth_info); + net_use_krb_machine_account(c); status = ads_startup(c, true, &ads); if (!ADS_ERR_OK(status)) { @@ -1192,7 +1197,6 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) const char *os_name = NULL; const char *os_version = NULL; bool modify_config = lp_config_backend_is_registry(); - struct user_auth_info *ai = c->auth_info;; if (c->display_usage) return net_ads_join_usage(c, argc, argv); @@ -1212,7 +1216,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) goto fail; } - if (!get_cmdline_auth_info_use_kerberos(ai)) { + if (!c->opt_kerberos) { use_in_memory_ccache(); } @@ -1262,8 +1266,6 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) /* Do the domain join here */ - set_cmdline_auth_info_getpass(ai); - r->in.domain_name = domain; r->in.create_upn = createupn; r->in.upn = machineupn; @@ -1271,10 +1273,10 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) r->in.os_name = os_name; r->in.os_version = os_version; r->in.dc_name = c->opt_host; - r->in.admin_account = get_cmdline_auth_info_username(ai); - r->in.admin_password = get_cmdline_auth_info_password(ai); + r->in.admin_account = c->opt_user_name; + r->in.admin_password = net_prompt_pass(c, c->opt_user_name); r->in.debug = true; - r->in.use_kerberos = get_cmdline_auth_info_use_kerberos(ai); + r->in.use_kerberos = c->opt_kerberos; r->in.modify_config = modify_config; r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | @@ -1585,7 +1587,6 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * char *prt_dn, *srv_dn, **srv_cn; char *srv_cn_escaped = NULL, *printername_escaped = NULL; LDAPMessage *res = NULL; - struct user_auth_info *ai = c->auth_info; if (argc < 1 || c->display_usage) { d_printf("Usage:\n" @@ -1617,9 +1618,8 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * nt_status = cli_full_connection(&cli, global_myname(), servername, &server_ss, 0, "IPC$", "IPC", - get_cmdline_auth_info_username(ai), - c->opt_workgroup, - get_cmdline_auth_info_password(ai), + c->opt_user_name, c->opt_workgroup, + c->opt_password ? c->opt_password : "", CLI_FULL_CONNECTION_USE_KERBEROS, Undefined, NULL); @@ -1807,8 +1807,8 @@ static int net_ads_printer(struct net_context *c, int argc, const char **argv) static int net_ads_password(struct net_context *c, int argc, const char **argv) { ADS_STRUCT *ads; - const char *auth_principal; - const char *auth_password; + const char *auth_principal = c->opt_user_name; + const char *auth_password = c->opt_password; char *realm = NULL; char *new_password = NULL; char *chr, *prompt; @@ -1823,9 +1823,10 @@ static int net_ads_password(struct net_context *c, int argc, const char **argv) return 0; } - auth_principal = get_cmdline_auth_info_username(c->auth_info); - set_cmdline_auth_info_getpass(c->auth_info); - auth_password = get_cmdline_auth_info_password(c->auth_info); + if (c->opt_user_name == NULL || c->opt_password == NULL) { + d_fprintf(stderr, "You must supply an administrator username/password\n"); + return -1; + } if (argc < 1) { d_fprintf(stderr, "ERROR: You must say which username to change password for\n"); @@ -1907,7 +1908,7 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv) return -1; } - set_cmdline_auth_info_use_machine_account(c->auth_info); + net_use_krb_machine_account(c); use_in_memory_ccache(); @@ -2289,7 +2290,6 @@ static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **ar TALLOC_CTX *mem_ctx = NULL; NTSTATUS status; int ret = -1; - struct user_auth_info *ai = c->auth_info; if (c->display_usage) { d_printf("Usage:\n" @@ -2303,11 +2303,11 @@ static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **ar goto out; } - set_cmdline_auth_info_getpass(ai); + c->opt_password = net_prompt_pass(c, c->opt_user_name); status = kerberos_return_pac(mem_ctx, - get_cmdline_auth_info_username(ai), - get_cmdline_auth_info_password(ai), + c->opt_user_name, + c->opt_password, 0, NULL, NULL, @@ -2340,7 +2340,6 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char ** TALLOC_CTX *mem_ctx = NULL; int ret = -1; NTSTATUS status; - struct user_auth_info *ai = c->auth_info; if (c->display_usage) { d_printf("Usage:\n" @@ -2354,10 +2353,10 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char ** goto out; } - set_cmdline_auth_info_getpass(ai); + c->opt_password = net_prompt_pass(c, c->opt_user_name); - ret = kerberos_kinit_password_ext(get_cmdline_auth_info_username(ai), - get_cmdline_auth_info_password(ai), + ret = kerberos_kinit_password_ext(c->opt_user_name, + c->opt_password, 0, NULL, NULL, diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c index a13f52c519..401079777f 100644 --- a/source3/utils/net_dom.c +++ b/source3/utils/net_dom.c @@ -368,11 +368,9 @@ int net_dom(struct net_context *c, int argc, const char **argv) return -1; } - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index 5a170790c5..0502373aa2 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -65,6 +65,5 @@ int net_help(struct net_context *c, int argc, const char **argv) } c->display_usage = true; - set_cmdline_auth_info_password(c->auth_info, ""); return net_run_function(c, argc, argv, "net help", func); } diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h index 8a09147aad..75ac032db9 100644 --- a/source3/utils/net_proto.h +++ b/source3/utils/net_proto.h @@ -459,6 +459,8 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst, struct rpc_pipe_client **pp_pipe_hnd, const struct ndr_syntax_id *interface); +int net_use_krb_machine_account(struct net_context *c); +int net_use_machine_account(struct net_context *c); bool net_find_server(struct net_context *c, const char *domain, unsigned flags, @@ -473,6 +475,7 @@ NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain, const char *server, struct sockaddr_storage *pss, unsigned flags, struct cli_state **pcli); +const char *net_prompt_pass(struct net_context *c, const char *user); int net_run_function(struct net_context *c, int argc, const char **argv, const char *whoami, struct functable *table); void net_display_usage_from_functable(struct functable *table); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 0118b4818a..f6f90030fe 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -25,8 +25,7 @@ #include "../libcli/auth/libcli_auth.h" static int net_mode_share; -static bool sync_files(struct copy_clistate *cp_clistate, const char *mask, - const struct user_auth_info *auth_info); +static bool sync_files(struct copy_clistate *cp_clistate, const char *mask); /** * @file net_rpc.c @@ -123,7 +122,6 @@ int run_rpc_command(struct net_context *c, DOM_SID *domain_sid; const char *domain_name; int ret = -1; - struct user_auth_info *ai = c->auth_info; /* make use of cli_state handed over as an argument, if possible */ if (!cli_arg) { @@ -173,10 +171,8 @@ int run_rpc_command(struct net_context *c, nt_status = cli_rpc_pipe_open_ntlmssp( cli, interface, PIPE_AUTH_LEVEL_PRIVACY, - lp_workgroup(), - get_cmdline_auth_info_username(ai), - get_cmdline_auth_info_password(ai), - &pipe_hnd); + lp_workgroup(), c->opt_user_name, + c->opt_password, &pipe_hnd); } else { nt_status = cli_rpc_pipe_open_noauth( cli, interface, @@ -944,12 +940,9 @@ int net_rpc_user(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -2763,12 +2756,9 @@ int net_rpc_group(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -3255,7 +3245,7 @@ static void copy_fn(const char *mnt, file_info *f, old_dir = local_state->cwd; local_state->cwd = dir; - if (!sync_files(local_state, new_mask, c->auth_info)) + if (!sync_files(local_state, new_mask)) printf("could not handle files\n"); local_state->cwd = old_dir; @@ -3302,18 +3292,15 @@ static void copy_fn(const char *mnt, file_info *f, * * @return Boolean result **/ -static bool sync_files(struct copy_clistate *cp_clistate, const char *mask, - const struct user_auth_info *auth_info) +static bool sync_files(struct copy_clistate *cp_clistate, const char *mask) { struct cli_state *targetcli; char *targetpath = NULL; DEBUG(3,("calling cli_list with mask: %s\n", mask)); - - if ( !cli_resolve_path(talloc_tos(), "", auth_info, - cp_clistate->cli_share_src, mask, &targetcli, - &targetpath ) ) { + if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src, + mask, &targetcli, &targetpath ) ) { d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n", mask, cli_errstr(cp_clistate->cli_share_src)); return false; @@ -3476,7 +3463,7 @@ static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c, goto done; } - if (!sync_files(&cp_clistate, mask, c->auth_info)) { + if (!sync_files(&cp_clistate, mask)) { d_fprintf(stderr, "could not handle files for share: %s\n", info502.name); nt_status = NT_STATUS_UNSUCCESSFUL; goto done; @@ -4577,12 +4564,9 @@ int net_rpc_share(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -4855,12 +4839,9 @@ int net_rpc_file(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -5550,7 +5531,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc, c->opt_workgroup = smb_xstrdup(domain_name); }; - set_cmdline_auth_info_username(c->auth_info, acct_name); + c->opt_user_name = acct_name; /* find the domain controller */ if (!net_find_pdc(&server_ss, pdc_name, domain_name)) { @@ -5647,9 +5628,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc, * Store the password in secrets db */ - if (!pdb_set_trusteddom_pw(domain_name, - get_cmdline_auth_info_password(c->auth_info), - domain_sid)) { + if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) { DEBUG(0, ("Storing password for trusted domain failed.\n")); cli_shutdown(cli); talloc_destroy(mem_ctx); @@ -7211,12 +7190,9 @@ int net_rpc(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index cae2491aed..ed0311317d 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -58,8 +58,7 @@ NTSTATUS net_rpc_join_ok(struct net_context *c, const char *domain, if (sec == SEC_ADS) { /* Connect to IPC$ using machine account's credentials. We don't use anonymous connection here, as it may be denied by server's local policy. */ - set_cmdline_auth_info_use_machine_account(c->auth_info); - set_cmdline_auth_info_machine_account_creds(c->auth_info); + net_use_machine_account(c); } else { /* some servers (e.g. WinNT) don't accept machine-authenticated diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index c0de247e7f..309be171cc 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -379,8 +379,8 @@ NTSTATUS rpc_vampire_keytab_internals(struct net_context *c, ctx->cli = pipe_hnd; ctx->ops = &libnet_samsync_keytab_ops; ctx->domain_name = domain_name; - ctx->username = get_cmdline_auth_info_username(c->auth_info); - ctx->password = get_cmdline_auth_info_password(c->auth_info); + ctx->username = c->opt_user_name; + ctx->password = c->opt_password; ctx->force_full_replication = c->opt_force_full_repl ? true : false; ctx->clean_old_entries = c->opt_clean_old_entries ? true : false; diff --git a/source3/utils/net_rpc_shell.c b/source3/utils/net_rpc_shell.c index dc13e91423..3aaed1ed18 100644 --- a/source3/utils/net_rpc_shell.c +++ b/source3/utils/net_rpc_shell.c @@ -220,12 +220,9 @@ int net_rpc_shell(struct net_context *c, int argc, const char **argv) if (libnetapi_init(&c->netapi_ctx) != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index 50f3c1db01..8bf9aac6f2 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -96,22 +96,22 @@ NTSTATUS connect_to_service(struct net_context *c, { NTSTATUS nt_status; int flags = 0; - struct user_auth_info *ai = c->auth_info; - set_cmdline_auth_info_getpass(ai); + c->opt_password = net_prompt_pass(c, c->opt_user_name); - if (get_cmdline_auth_info_use_kerberos(ai)) { - flags |= CLI_FULL_CONNECTION_USE_KERBEROS | - CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; + if (c->opt_kerberos) { + flags |= CLI_FULL_CONNECTION_USE_KERBEROS; + } + + if (c->opt_kerberos && c->opt_password) { + flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; } nt_status = cli_full_connection(cli_ctx, NULL, server_name, server_ss, c->opt_port, service_name, service_type, - get_cmdline_auth_info_username(ai), - c->opt_workgroup, - get_cmdline_auth_info_password(ai), - flags, Undefined, NULL); + c->opt_user_name, c->opt_workgroup, + c->opt_password, flags, Undefined, NULL); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, "Could not connect to server %s\n", server_name); @@ -131,10 +131,10 @@ NTSTATUS connect_to_service(struct net_context *c, return nt_status; } - if (get_cmdline_auth_info_smb_encrypt(ai)) { + if (c->smb_encrypt) { nt_status = cli_force_encryption(*cli_ctx, - get_cmdline_auth_info_username(ai), - get_cmdline_auth_info_password(ai), + c->opt_user_name, + c->opt_password, c->opt_workgroup); if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) { @@ -234,12 +234,14 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, { NTSTATUS nt_status; char *user_and_realm = NULL; - struct user_auth_info *ai = c->auth_info; /* FIXME: Should get existing kerberos ticket if possible. */ - set_cmdline_auth_info_getpass(ai); + c->opt_password = net_prompt_pass(c, c->opt_user_name); + if (!c->opt_password) { + return NT_STATUS_NO_MEMORY; + } - user_and_realm = get_user_and_realm(get_cmdline_auth_info_username(ai)); + user_and_realm = get_user_and_realm(c->opt_user_name); if (!user_and_realm) { return NT_STATUS_NO_MEMORY; } @@ -248,7 +250,7 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, server_ss, c->opt_port, "IPC$", "IPC", user_and_realm, c->opt_workgroup, - get_cmdline_auth_info_password(ai), + c->opt_password, CLI_FULL_CONNECTION_USE_KERBEROS, Undefined, NULL); @@ -259,10 +261,10 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, return nt_status; } - if (get_cmdline_auth_info_smb_encrypt(ai)) { + if (c->smb_encrypt) { nt_status = cli_cm_force_encryption(*cli_ctx, user_and_realm, - get_cmdline_auth_info_password(ai), + c->opt_password, c->opt_workgroup, "IPC$"); if (!NT_STATUS_IS_OK(nt_status)) { @@ -326,6 +328,50 @@ NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst, return nt_status; } +/**************************************************************************** + Use the local machine account (krb) and password for this session. +****************************************************************************/ + +int net_use_krb_machine_account(struct net_context *c) +{ + char *user_name = NULL; + + if (!secrets_init()) { + d_fprintf(stderr, "ERROR: Unable to open secrets database\n"); + exit(1); + } + + c->opt_password = secrets_fetch_machine_password( + c->opt_target_workgroup, NULL, NULL); + if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) { + return -1; + } + c->opt_user_name = user_name; + return 0; +} + +/**************************************************************************** + Use the machine account name and password for this session. +****************************************************************************/ + +int net_use_machine_account(struct net_context *c) +{ + char *user_name = NULL; + + if (!secrets_init()) { + d_fprintf(stderr, "ERROR: Unable to open secrets database\n"); + exit(1); + } + + c->opt_password = secrets_fetch_machine_password( + c->opt_target_workgroup, NULL, NULL); + if (asprintf(&user_name, "%s$", global_myname()) == -1) { + return -1; + } + c->opt_user_name = user_name; + return 0; +} + bool net_find_server(struct net_context *c, const char *domain, unsigned flags, @@ -489,6 +535,33 @@ done: /**************************************************************************** ****************************************************************************/ +const char *net_prompt_pass(struct net_context *c, const char *user) +{ + char *prompt = NULL; + const char *pass = NULL; + + if (c->opt_password) { + return c->opt_password; + } + + if (c->opt_machine_pass) { + return NULL; + } + + if (c->opt_kerberos && !c->opt_user_specified) { + return NULL; + } + + if (asprintf(&prompt, "Enter %s's password:", user) == -1) { + return NULL; + } + + pass = getpass(prompt); + SAFE_FREE(prompt); + + return pass; +} + int net_run_function(struct net_context *c, int argc, const char **argv, const char *whoami, struct functable *table) { -- cgit From 84eced142551a1986ba727d4c57aed1296ac87b4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Jul 2009 11:05:21 +0200 Subject: librpc: fix the merged build of ndr_frsrpc.c metze --- librpc/ndr/ndr_frsrpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/ndr/ndr_frsrpc.c b/librpc/ndr/ndr_frsrpc.c index c99745999c..e0c7f1cd75 100644 --- a/librpc/ndr/ndr_frsrpc.c +++ b/librpc/ndr/ndr_frsrpc.c @@ -19,7 +19,7 @@ along with this program. If not, see . */ -#include "replace.h" +#include "includes.h" #include "librpc/gen_ndr/ndr_frsrpc.h" enum ndr_err_code ndr_push_frsrpc_CommPktChunkCtr(struct ndr_push *ndr, -- cgit From 4b42927ec31a0819b1e5ec415fd1a16061cff677 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 13:57:56 -0700 Subject: s3: Convert some callers of vfs_stat_smb_fname to SMB_VFS_STAT() --- source3/smbd/globals.h | 1 - source3/smbd/posix_acls.c | 24 ++++++++++++++++++------ source3/smbd/smb2_getinfo.c | 10 ---------- source3/smbd/trans2.c | 28 +++++++++++++++++++--------- 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index cd3e054d1a..434204b60d 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -213,7 +213,6 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, NTSTATUS smbd_do_qfsinfo(connection_struct *conn, TALLOC_CTX *mem_ctx, uint16_t info_level, - SMB_STRUCT_STAT st, uint16_t flags2, unsigned int max_data_bytes, char **ppdata, diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index fb2cda40ce..0a3b0dff75 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3372,33 +3372,45 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, uint32_t security_info, SEC_DESC **ppdesc) { - SMB_STRUCT_STAT sbuf; SMB_ACL_T posix_acl = NULL; SMB_ACL_T def_acl = NULL; struct pai_val *pal; + struct smb_filename *smb_fname = NULL; + NTSTATUS status; *ppdesc = NULL; DEBUG(10,("posix_get_nt_acl: called for file %s\n", name )); + status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + /* Get the stat struct for the owner info. */ - if(vfs_stat_smb_fname(conn, name, &sbuf) != 0) { - return map_nt_error_from_unix(errno); + if(SMB_VFS_STAT(conn, smb_fname) != 0) { + status = map_nt_error_from_unix(errno); + goto out; } /* Get the ACL from the path. */ posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS); /* If it's a directory get the default POSIX ACL. */ - if(S_ISDIR(sbuf.st_ex_mode)) { + if(S_ISDIR(smb_fname->st.st_ex_mode)) { def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT); def_acl = free_empty_sys_acl(conn, def_acl); } pal = load_inherited_info(conn, name); - return posix_get_nt_acl_common(conn, name, &sbuf, pal, posix_acl, - def_acl, security_info, ppdesc); + status = posix_get_nt_acl_common(conn, name, &smb_fname->st, pal, + posix_acl, def_acl, security_info, + ppdesc); + out: + TALLOC_FREE(smb_fname); + return status; } /**************************************************************************** diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index dda79c209f..5a6e3d7ecb 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -367,22 +367,12 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, char *data = NULL; int data_size = 0; NTSTATUS status; - SMB_STRUCT_STAT st; /* the levels directly map to the passthru levels */ file_info_level = in_file_info_class + 1000; - if (vfs_stat_smb_fname(conn,".",&st)!=0) { - DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", - strerror(errno))); - status = map_nt_error_from_unix(errno); - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - status = smbd_do_qfsinfo(conn, state, file_info_level, - st, STR_UNICODE, in_output_buffer_length, &data, diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index cac0147c4d..856fd9432d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2682,7 +2682,6 @@ static void samba_extended_info_version(struct smb_extended_info *extended_info) NTSTATUS smbd_do_qfsinfo(connection_struct *conn, TALLOC_CTX *mem_ctx, uint16_t info_level, - SMB_STRUCT_STAT st, uint16_t flags2, unsigned int max_data_bytes, char **ppdata, @@ -2694,6 +2693,9 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, int snum = SNUM(conn); char *fstype = lp_fstype(SNUM(conn)); uint32 additional_flags = 0; + struct smb_filename *smb_fname_dot = NULL; + SMB_STRUCT_STAT st; + NTSTATUS status; if (IS_IPC(conn)) { if (info_level != SMB_QUERY_CIFS_UNIX_INFO) { @@ -2706,6 +2708,21 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level)); + status = create_synthetic_smb_fname(talloc_tos(), ".", NULL, NULL, + &smb_fname_dot); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if(SMB_VFS_STAT(conn, smb_fname_dot) != 0) { + DEBUG(2,("stat of . failed (%s)\n", strerror(errno))); + TALLOC_FREE(smb_fname_dot); + return map_nt_error_from_unix(errno); + } + + st = smb_fname_dot->st; + TALLOC_FREE(smb_fname_dot); + *ppdata = (char *)SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); if (*ppdata == NULL) { @@ -3228,7 +3245,6 @@ static void call_trans2qfsinfo(connection_struct *conn, char *params = *pparams; uint16_t info_level; int data_len = 0; - SMB_STRUCT_STAT st; NTSTATUS status; if (total_params < 2) { @@ -3251,14 +3267,8 @@ static void call_trans2qfsinfo(connection_struct *conn, DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); - if(vfs_stat_smb_fname(conn,".",&st)!=0) { - DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); - reply_doserror(req, ERRSRV, ERRinvdevice); - return; - } - status = smbd_do_qfsinfo(conn, req, - info_level, st, + info_level, req->flags2, max_data_bytes, ppdata, &data_len); -- cgit From 83284e13f91f685b8dcccb9202e33fe64e6930b2 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 15:55:25 -0700 Subject: s3: Convert some callers of vfs_lstat_smb_fname to SMB_VFS_LSTAT() --- source3/smbd/msdfs.c | 20 ++++++++++++++------ source3/smbd/vfs.c | 19 ++++++++++++++++--- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index d40b8a8902..2b63eb1743 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -411,7 +411,6 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx, char **pp_link_target, SMB_STRUCT_STAT *sbufp) { - SMB_STRUCT_STAT st; int referral_len = 0; #if defined(HAVE_BROKEN_READLINK) char link_target_buf[PATH_MAX]; @@ -420,6 +419,8 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx, #endif size_t bufsize = 0; char *link_target = NULL; + struct smb_filename *smb_fname = NULL; + NTSTATUS status; if (pp_link_target) { bufsize = 1024; @@ -433,21 +434,28 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx, link_target = link_target_buf; } - if (sbufp == NULL) { - sbufp = &st; + status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + goto err; } - if (vfs_lstat_smb_fname(conn, path, sbufp) != 0) { + if (SMB_VFS_LSTAT(conn, smb_fname) != 0) { DEBUG(5,("is_msdfs_link_read_target: %s does not exist.\n", path)); + TALLOC_FREE(smb_fname); goto err; } - - if (!S_ISLNK(sbufp->st_ex_mode)) { + if (!S_ISLNK(smb_fname->st.st_ex_mode)) { DEBUG(5,("is_msdfs_link_read_target: %s is not a link.\n", path)); + TALLOC_FREE(smb_fname); goto err; } + if (sbufp != NULL) { + *sbufp = smb_fname->st; + } + TALLOC_FREE(smb_fname); referral_len = SMB_VFS_READLINK(conn, path, link_target, bufsize - 1); if (referral_len == -1) { diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 55495183bd..cd78c7962e 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -972,15 +972,28 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) #ifdef S_ISLNK if (!lp_symlinks(SNUM(conn))) { - SMB_STRUCT_STAT statbuf; - if ( (vfs_lstat_smb_fname(conn,fname,&statbuf) != -1) && - (S_ISLNK(statbuf.st_ex_mode)) ) { + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + + status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, + NULL, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + if (free_resolved_name) { + SAFE_FREE(resolved_name); + } + return status; + } + + if ( (SMB_VFS_LSTAT(conn, smb_fname) != -1) && + (S_ISLNK(smb_fname->st.st_ex_mode)) ) { if (free_resolved_name) { SAFE_FREE(resolved_name); } DEBUG(3,("reduce_name: denied: file path name %s is a symlink\n",resolved_name)); + TALLOC_FREE(smb_fname); return NT_STATUS_ACCESS_DENIED; } + TALLOC_FREE(smb_fname); } #endif -- cgit From 07d3b69b55c37f26ba6fa8b0c1c59e800325b435 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Wed, 22 Jul 2009 09:52:09 -0700 Subject: s3: Change unix_convert to use an smb_filename struct internally This allows SMB_VFS_[L]STAT to be called directly. Additionally, I changed NTSTATUS result to be named status for consistency. I also removed the stat_cache_add() from build_stream_path() because stat_cache_lookup() is never actually called on a file with a stream. There is no reason why the stat cache couldn't be consulted for streams in the future. Jeremy/Volker, please take a look at this one when you get a chance. --- source3/smbd/filename.c | 291 +++++++++++++++++++++++++---------------------- source3/smbd/statcache.c | 15 ++- 2 files changed, 168 insertions(+), 138 deletions(-) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 541b0cd3cb..09f9a418bd 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -117,23 +117,21 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, struct smb_filename **smb_fname_out, uint32_t ucf_flags) { - SMB_STRUCT_STAT st; struct smb_filename *smb_fname = NULL; char *start, *end; char *dirpath = NULL; - char *name = NULL; char *stream = NULL; bool component_was_mangled = False; bool name_has_wildcard = False; bool posix_pathnames = false; bool allow_wcard_last_component = ucf_flags & UCF_ALLOW_WCARD_LCOMP; bool save_last_component = ucf_flags & UCF_SAVE_LCOMP; - NTSTATUS result; + NTSTATUS status; int ret = -1; *smb_fname_out = NULL; - smb_fname = talloc_zero(talloc_tos(), struct smb_filename); + smb_fname = talloc_zero(ctx, struct smb_filename); if (smb_fname == NULL) { return NT_STATUS_NO_MEMORY; } @@ -143,10 +141,10 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, filename - so don't convert them */ if (!(smb_fname->base_name = talloc_strdup(smb_fname, orig_path))) { - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } - *smb_fname_out = smb_fname; - return NT_STATUS_OK; + goto done; } DEBUG(5, ("unix_convert called on file \"%s\"\n", orig_path)); @@ -174,15 +172,16 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if (!*orig_path) { - if (!(name = talloc_strdup(ctx,"."))) { - return NT_STATUS_NO_MEMORY; + if (!(smb_fname->base_name = talloc_strdup(smb_fname, "."))) { + status = NT_STATUS_NO_MEMORY; + goto err; } - if (vfs_stat_smb_fname(conn,name,&st) == 0) { - smb_fname->st = st; - } else { - return map_nt_error_from_unix(errno); + if (SMB_VFS_STAT(conn, smb_fname) != 0) { + status = map_nt_error_from_unix(errno); + goto err; } - DEBUG(5,("conversion finished \"\" -> %s\n",name)); + DEBUG(5, ("conversion finished \"\" -> %s\n", + smb_fname->base_name)); goto done; } @@ -190,17 +189,19 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, orig_path[1] == '\0')) { /* Start of pathname can't be "." only. */ if (orig_path[1] == '\0' || orig_path[2] == '\0') { - result = NT_STATUS_OBJECT_NAME_INVALID; + status = NT_STATUS_OBJECT_NAME_INVALID; } else { - result =determine_path_error( - &orig_path[2], allow_wcard_last_component); + status =determine_path_error(&orig_path[2], + allow_wcard_last_component); } - return result; + goto err; } - if (!(name = talloc_strdup(ctx, orig_path))) { + /* Start with the full orig_path as given by the caller. */ + if (!(smb_fname->base_name = talloc_strdup(smb_fname, orig_path))) { DEBUG(0, ("talloc_strdup failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } /* @@ -214,7 +215,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if (conn->case_sensitive && !conn->case_preserve && !conn->short_case_preserve) { - strnorm(name, lp_defaultcase(SNUM(conn))); + strnorm(smb_fname->base_name, lp_defaultcase(SNUM(conn))); } /* @@ -222,44 +223,60 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if(save_last_component) { - end = strrchr_m(name, '/'); + end = strrchr_m(smb_fname->base_name, '/'); if (end) { - smb_fname->original_lcomp = talloc_strdup(ctx, + smb_fname->original_lcomp = talloc_strdup(smb_fname, end + 1); } else { - smb_fname->original_lcomp = talloc_strdup(ctx, name); + smb_fname->original_lcomp = + talloc_strdup(smb_fname, smb_fname->base_name); + } + if (smb_fname->original_lcomp == NULL) { + status = NT_STATUS_NO_MEMORY; + goto err; } } posix_pathnames = lp_posix_pathnames(); - /* Strip off the stream. Should we use any of the other stream parsing - * at this point? Also, should we set the is_stream bit? */ + /* + * Strip off the stream, and add it back when we're done with the + * base_name. + */ if (!posix_pathnames) { - stream = strchr_m(name, ':'); + stream = strchr_m(smb_fname->base_name, ':'); if (stream != NULL) { - char *tmp = talloc_strdup(ctx, stream); + char *tmp = talloc_strdup(smb_fname, stream); if (tmp == NULL) { - TALLOC_FREE(name); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } + /* + * Since this is actually pointing into + * smb_fname->base_name this truncates base_name. + */ *stream = '\0'; stream = tmp; } } - start = name; + start = smb_fname->base_name; - /* If we're providing case insentive semantics or + /* + * If we're providing case insentive semantics or * the underlying filesystem is case insensitive, * then a case-normalized hit in the stat-cache is * authoratitive. JRA. + * + * Note: We're only checking base_name. The stream_name will be + * added and verified in build_stream_path(). */ - if((!conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) && - stat_cache_lookup(conn, &name, &dirpath, &start, &st)) { - smb_fname->st = st; + if((!conn->case_sensitive || !(conn->fs_capabilities & + FILE_CASE_SENSITIVE_SEARCH)) && + stat_cache_lookup(conn, &smb_fname->base_name, &dirpath, &start, + &smb_fname->st)) { goto done; } @@ -270,43 +287,46 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) { DEBUG(0, ("talloc_strdup failed\n")); - TALLOC_FREE(name); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } /* - * stat the name - if it exists then we are all done! + * stat the name - if it exists then we can add the stream back (if + * there was one) and be done! */ if (posix_pathnames) { - ret = vfs_lstat_smb_fname(conn,name,&st); + ret = SMB_VFS_LSTAT(conn, smb_fname); } else { - ret = vfs_stat_smb_fname(conn,name,&st); + ret = SMB_VFS_STAT(conn, smb_fname); } if (ret == 0) { /* Ensure we catch all names with in "/." this is disallowed under Windows. */ - const char *p = strstr(name, "/."); /* mb safe. */ + const char *p = strstr(smb_fname->base_name, "/."); /*mb safe*/ if (p) { if (p[2] == '/') { /* Error code within a pathname. */ - result = NT_STATUS_OBJECT_PATH_NOT_FOUND; + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; goto fail; } else if (p[2] == '\0') { /* Error code at the end of a pathname. */ - result = NT_STATUS_OBJECT_NAME_INVALID; + status = NT_STATUS_OBJECT_NAME_INVALID; goto fail; } } - stat_cache_add(orig_path, name, conn->case_sensitive); - DEBUG(5,("conversion finished %s -> %s\n",orig_path, name)); - smb_fname->st = st; + /* Add the path (not including the stream) to the cache. */ + stat_cache_add(orig_path, smb_fname->base_name, + conn->case_sensitive); + DEBUG(5,("conversion of base_name finished %s -> %s\n", + orig_path, smb_fname->base_name)); goto done; } DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n", - name, dirpath, start)); + smb_fname->base_name, dirpath, start)); /* * A special case - if we don't have any mangling chars and are case @@ -314,8 +334,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * won't help. */ - if ((conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) && - !mangle_is_mangled(name, conn->params)) { + if ((conn->case_sensitive || !(conn->fs_capabilities & + FILE_CASE_SENSITIVE_SEARCH)) && + !mangle_is_mangled(smb_fname->base_name, conn->params)) { goto done; } @@ -354,11 +375,12 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if (save_last_component) { TALLOC_FREE(smb_fname->original_lcomp); - smb_fname->original_lcomp = talloc_strdup(ctx, + smb_fname->original_lcomp = talloc_strdup(smb_fname, end ? end + 1 : start); if (!smb_fname->original_lcomp) { DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } } @@ -367,9 +389,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if (ISDOT(start)) { if (!end) { /* Error code at the end of a pathname. */ - result = NT_STATUS_OBJECT_NAME_INVALID; + status = NT_STATUS_OBJECT_NAME_INVALID; } else { - result = determine_path_error(end+1, + status = determine_path_error(end+1, allow_wcard_last_component); } goto fail; @@ -382,13 +404,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, /* Wildcard not valid anywhere. */ if (name_has_wildcard && !allow_wcard_last_component) { - result = NT_STATUS_OBJECT_NAME_INVALID; + status = NT_STATUS_OBJECT_NAME_INVALID; goto fail; } /* Wildcards never valid within a pathname. */ if (name_has_wildcard && end) { - result = NT_STATUS_OBJECT_NAME_INVALID; + status = NT_STATUS_OBJECT_NAME_INVALID; goto fail; } @@ -397,9 +419,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if (posix_pathnames) { - ret = vfs_lstat_smb_fname(conn,name, &st); + ret = SMB_VFS_LSTAT(conn, smb_fname); } else { - ret = vfs_stat_smb_fname(conn,name, &st); + ret = SMB_VFS_STAT(conn, smb_fname); } if (ret == 0) { @@ -407,7 +429,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * It exists. it must either be a directory or this must * be the last part of the path for it to be OK. */ - if (end && !S_ISDIR(st.st_ex_mode)) { + if (end && !S_ISDIR(smb_fname->st.st_ex_mode)) { /* * An intermediate part of the name isn't * a directory. @@ -422,25 +444,15 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * applications depend on the difference between * these two errors. */ - result = NT_STATUS_OBJECT_PATH_NOT_FOUND; + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; goto fail; } - if (!end) { - /* - * We just scanned for, and found the end of - * the path. We must return the valid stat - * struct. JRA. - */ - - smb_fname->st = st; - } - } else { char *found_name = NULL; /* Stat failed - ensure we don't use it. */ - SET_STAT_INVALID(st); + SET_STAT_INVALID(smb_fname->st); /* * Reset errno so we can detect @@ -486,11 +498,11 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if (errno == ENOENT || errno == ENOTDIR || errno == ELOOP) { - result = + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; } else { - result = + status = map_nt_error_from_unix(errno); } goto fail; @@ -511,10 +523,10 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if (errno == ENOTDIR || errno == ELOOP) { - result = + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; } else { - result = + status = map_nt_error_from_unix(errno); } goto fail; @@ -546,12 +558,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, &unmangled, conn->params)) { char *tmp; - size_t start_ofs = start - name; + size_t start_ofs = + start - smb_fname->base_name; if (*dirpath != '\0') { - tmp = talloc_asprintf(ctx, - "%s/%s", dirpath, - unmangled); + tmp = talloc_asprintf( + smb_fname, "%s/%s", + dirpath, unmangled); TALLOC_FREE(unmangled); } else { @@ -559,11 +572,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, } if (tmp == NULL) { DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } - TALLOC_FREE(name); - name = tmp; - start = name + start_ofs; + TALLOC_FREE(smb_fname->base_name); + smb_fname->base_name = tmp; + start = + smb_fname->base_name + start_ofs; end = start + strlen(start); } @@ -578,46 +593,50 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if (end) { char *tmp; - size_t start_ofs = start - name; + size_t start_ofs = + start - smb_fname->base_name; if (*dirpath != '\0') { - tmp = talloc_asprintf(ctx, + tmp = talloc_asprintf(smb_fname, "%s/%s/%s", dirpath, found_name, end+1); } else { - tmp = talloc_asprintf(ctx, + tmp = talloc_asprintf(smb_fname, "%s/%s", found_name, end+1); } if (tmp == NULL) { DEBUG(0, ("talloc_asprintf failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } - TALLOC_FREE(name); - name = tmp; - start = name + start_ofs; + TALLOC_FREE(smb_fname->base_name); + smb_fname->base_name = tmp; + start = smb_fname->base_name + start_ofs; end = start + strlen(found_name); *end = '\0'; } else { char *tmp; - size_t start_ofs = start - name; + size_t start_ofs = + start - smb_fname->base_name; if (*dirpath != '\0') { - tmp = talloc_asprintf(ctx, + tmp = talloc_asprintf(smb_fname, "%s/%s", dirpath, found_name); } else { - tmp = talloc_strdup(ctx, + tmp = talloc_strdup(smb_fname, found_name); } if (tmp == NULL) { DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } - TALLOC_FREE(name); - name = tmp; - start = name + start_ofs; + TALLOC_FREE(smb_fname->base_name); + smb_fname->base_name = tmp; + start = smb_fname->base_name + start_ofs; /* * We just scanned for, and found the end of @@ -626,17 +645,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if (posix_pathnames) { - ret = vfs_lstat_smb_fname(conn,name, - &st); + ret = SMB_VFS_LSTAT(conn, smb_fname); } else { - ret = vfs_stat_smb_fname(conn,name, - &st); + ret = SMB_VFS_STAT(conn, smb_fname); } - if (ret == 0) { - smb_fname->st = st; - } else { - SET_STAT_INVALID(st); + if (ret != 0) { + SET_STAT_INVALID(smb_fname->st); } } @@ -649,12 +664,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * We should never provide different behaviors * depending on DEVELOPER!!! */ - if (VALID_STAT(st)) { + if (VALID_STAT(smb_fname->st)) { bool delete_pending; - get_file_infos(vfs_file_id_from_sbuf(conn, &st), + get_file_infos(vfs_file_id_from_sbuf(conn, + &smb_fname->st), &delete_pending, NULL); if (delete_pending) { - result = NT_STATUS_DELETE_PENDING; + status = NT_STATUS_DELETE_PENDING; goto fail; } } @@ -669,7 +685,8 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, "%s/%s", dirpath, start); if (!tmp) { DEBUG(0, ("talloc_asprintf failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } TALLOC_FREE(dirpath); dirpath = tmp; @@ -678,15 +695,15 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, TALLOC_FREE(dirpath); if (!(dirpath = talloc_strdup(ctx,start))) { DEBUG(0, ("talloc_strdup failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } } /* - * Don't cache a name with mangled or wildcard components - * as this can change the size. + * Cache the dirpath thus far. Don't cache a name with mangled + * or wildcard components as this can change the size. */ - if(!component_was_mangled && !name_has_wildcard) { stat_cache_add(orig_path, dirpath, conn->case_sensitive); @@ -701,29 +718,30 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, } /* - * Don't cache a name with mangled or wildcard components - * as this can change the size. + * Cache the full path. Don't cache a name with mangled or wildcard + * components as this can change the size. */ if(!component_was_mangled && !name_has_wildcard) { - stat_cache_add(orig_path, name, conn->case_sensitive); + stat_cache_add(orig_path, smb_fname->base_name, + conn->case_sensitive); } /* * The name has been resolved. */ - DEBUG(5,("conversion finished %s -> %s\n",orig_path, name)); + DEBUG(5,("conversion finished %s -> %s\n", orig_path, + smb_fname->base_name)); done: - smb_fname->base_name = name; - + /* Add back the stream if one was stripped off originally. */ if (stream != NULL) { smb_fname->stream_name = stream; /* Check path now that the base_name has been converted. */ - result = build_stream_path(ctx, conn, orig_path, smb_fname); - if (!NT_STATUS_IS_OK(result)) { + status = build_stream_path(ctx, conn, orig_path, smb_fname); + if (!NT_STATUS_IS_OK(status)) { goto fail; } } @@ -733,20 +751,23 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, fail: DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start)); if (*dirpath != '\0') { - smb_fname->base_name = talloc_asprintf(ctx, "%s/%s", dirpath, - start); + smb_fname->base_name = talloc_asprintf(smb_fname, "%s/%s", + dirpath, start); } else { - smb_fname->base_name = talloc_strdup(ctx, start); + smb_fname->base_name = talloc_strdup(smb_fname, start); } if (!smb_fname->base_name) { DEBUG(0, ("talloc_asprintf failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } *smb_fname_out = smb_fname; - TALLOC_FREE(name); TALLOC_FREE(dirpath); - return result; + return status; + err: + TALLOC_FREE(smb_fname); + return status; } /**************************************************************************** @@ -942,6 +963,7 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, struct stream_struct *streams = NULL; if (SMB_VFS_STAT(conn, smb_fname) == 0) { + DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname))); return NT_STATUS_OK; } @@ -988,21 +1010,16 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, TALLOC_FREE(smb_fname->stream_name); - smb_fname->stream_name = talloc_strdup(mem_ctx, streams[i].name); + smb_fname->stream_name = talloc_strdup(smb_fname, streams[i].name); + if (smb_fname->stream_name == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } SET_STAT_INVALID(smb_fname->st); if (SMB_VFS_STAT(conn, smb_fname) == 0) { - char *result = NULL; - - status = get_full_smb_filename(mem_ctx, smb_fname, &result); - if (!NT_STATUS_IS_OK(status)) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - stat_cache_add(orig_path, result, conn->case_sensitive); - TALLOC_FREE(result); + DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname))); } status = NT_STATUS_OK; fail: diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c index daed9f8225..da52cc05d4 100644 --- a/source3/smbd/statcache.c +++ b/source3/smbd/statcache.c @@ -175,6 +175,8 @@ bool stat_cache_lookup(connection_struct *conn, DATA_BLOB data_val; char *name; TALLOC_CTX *ctx = talloc_tos(); + struct smb_filename *smb_fname = NULL; + NTSTATUS status; *pp_dirpath = NULL; *pp_start = *pp_name; @@ -274,14 +276,25 @@ bool stat_cache_lookup(connection_struct *conn, "-> [%s]\n", chk_name, translated_path )); DO_PROFILE_INC(statcache_hits); - if (vfs_stat_smb_fname(conn, translated_path, pst) != 0) { + status = create_synthetic_smb_fname(talloc_tos(), translated_path, + NULL, NULL, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(chk_name); + TALLOC_FREE(translated_path); + return false; + } + + if (SMB_VFS_STAT(conn, smb_fname) != 0) { /* Discard this entry - it doesn't exist in the filesystem. */ memcache_delete(smbd_memcache(), STAT_CACHE, data_blob_const(chk_name, strlen(chk_name))); TALLOC_FREE(chk_name); TALLOC_FREE(translated_path); + TALLOC_FREE(smb_fname); return False; } + *pst = smb_fname->st; + TALLOC_FREE(smb_fname); if (!sizechanged) { memcpy(*pp_name, translated_path, -- cgit From 109b9dcad9b3fbb8a3289cd73471a5881cbd40a6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Jul 2009 15:48:32 +0200 Subject: frsrpc.idl: add definition for frsrpc_FrsStartPromotionParent() metze --- librpc/idl/frsrpc.idl | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/librpc/idl/frsrpc.idl b/librpc/idl/frsrpc.idl index 233fbcb174..cab155295d 100644 --- a/librpc/idl/frsrpc.idl +++ b/librpc/idl/frsrpc.idl @@ -358,7 +358,28 @@ interface frsrpc /*****************/ /* Function 0x02 */ - [todo] void FRSRPC_START_PROMOTION_PARENT(); + typedef [v1_enum,flag(NDR_PAHEX)] enum { + FRSRPC_PARENT_AUTH_LEVEL_ENCRYPTED_KERBEROS = 0x00000000, + FRSRPC_PARENT_AUTH_LEVEL_NO_AUTHENTICATION = 0x00000001 + } frsrpc_PartnerAuthLevel; + + WERROR frsrpc_FrsStartPromotionParent( + [in,unique,string,charset(UTF16)] uint16 *parent_account, + [in,unique,string,charset(UTF16)] uint16 *parent_password, + [in,unique,string,charset(UTF16)] uint16 *replica_set_name, + [in,unique,string,charset(UTF16)] uint16 *replica_set_type, + [in,unique,string,charset(UTF16)] uint16 *connection_name, + [in,unique,string,charset(UTF16)] uint16 *partner_name, + [in,unique,string,charset(UTF16)] uint16 *partner_princ_name, + [in] frsrpc_PartnerAuthLevel partner_auth_level, + [in,value(16),range(16,16)] uint32 __ndr_guid_size, + [in,unique,subcontext(4),subcontext_size(16)] + GUID *connection_guid, + [in,unique,subcontext(4),subcontext_size(16)] + GUID *partner_guid, + [in,out,unique,subcontext(4),subcontext_size(16)] + GUID *parent_guid + ); /*****************/ /* Function 0x03 */ -- cgit From 2cc4a43d0e204acebb9b23fd0abbdb8e7e876128 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Jul 2009 10:55:39 +0200 Subject: frstrans.idl: add new DFS-R FrsTransport interface with dummy functions metze --- librpc/idl/frstrans.idl | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ source4/librpc/config.mk | 9 +++++- 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 librpc/idl/frstrans.idl diff --git a/librpc/idl/frstrans.idl b/librpc/idl/frstrans.idl new file mode 100644 index 0000000000..c79aabf773 --- /dev/null +++ b/librpc/idl/frstrans.idl @@ -0,0 +1,83 @@ +#include "idl_types.h" + +import "misc.idl"; + +[ + uuid("897e2e5f-93f3-4376-9c9c-fd2277495c27"), + version(1.0), + endpoint("ncacn_ip_tcp:", "ncalrpc:"), + helpstring("File Replication Service DFS-R"), + pointer_default(unique) +] +interface frstrans +{ + /*****************/ + /* Function 0x00 */ + [todo] void FRSTRANS_CHECK_CONNECTIVITY(); + + /*****************/ + /* Function 0x01 */ + [todo] void FRSTRANS_ESTABLISH_CONNECTION(); + + /*****************/ + /* Function 0x02 */ + [todo] void FRSTRANS_ESTABLISH_SESSION(); + + /*****************/ + /* Function 0x03 */ + [todo] void FRSTRANS_REQUEST_UPDATES(); + + /*****************/ + /* Function 0x04 */ + [todo] void FRSTRANS_REQUEST_VERSION_VECTOR(); + + /*****************/ + /* Function 0x05 */ + [todo] void FRSTRANS_ASYNC_POLL(); + + /*****************/ + /* Function 0x06 */ + [todo] void FRSTRANS_REQUEST_RECORDS(); + + /*****************/ + /* Function 0x07 */ + [todo] void FRSTRANS_UPDATE_CANCEL(); + + /*****************/ + /* Function 0x08 */ + [todo] void FRSTRANS_RAW_GET_FILE_DATA(); + + /*****************/ + /* Function 0x09 */ + [todo] void FRSTRANS_RDC_GET_SIGNATURES(); + + /*****************/ + /* Function 0x0a */ + [todo] void FRSTRANS_RDC_PUSH_SOURCE_NEEDS(); + + /*****************/ + /* Function 0x0b */ + [todo] void FRSTRANS_RDC_GET_FILE_DATA(); + + /*****************/ + /* Function 0x0c */ + [todo] void FRSTRANS_RDC_CLOSE(); + + /*****************/ + /* Function 0x0d */ + [todo] void FRSTRANS_INITIALIZE_FILE_TRANSFER_ASYNC(); + + /*****************/ + /* Function 0x0e */ + [todo] void FRSTRANS_OPNUM_0E_NOT_USED_ON_THE_WIRE(); + + /* The following functions are new in Windows 2008 */ + + /*****************/ + /* Function 0x0f */ + [todo] void FRSTRANS_RAW_GET_FILE_DATA_ASYNC(); + + /*****************/ + /* Function 0x10 */ + [todo] void FRSTRANS_RDC_GET_FILE_DATA_ASYNC(); +} diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index e96cf2c516..9cb2d7faf6 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -119,6 +119,11 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_FRSAPI_OBJ_FILES = ../librpc/gen_ndr/ndr_frsapi.o +[SUBSYSTEM::NDR_FRSTRANS] +PUBLIC_DEPENDENCIES = LIBNDR + +NDR_FRSTRANS_OBJ_FILES = ../librpc/gen_ndr/ndr_frstrans.o + [SUBSYSTEM::NDR_DRSUAPI] PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_STANDARD ASN1_UTIL @@ -338,7 +343,9 @@ PUBLIC_DEPENDENCIES = \ NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \ NDR_ROT NDR_DRSBLOBS NDR_NBT NDR_WINSREPL NDR_SECURITY \ NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \ - NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND \ + NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND \ + NDR_FRSRPC NDR_FRSAPI NDR_FRSTRANS \ + NDR_NFS4ACL NDR_NTP_SIGND \ NDR_DCOM NDR_WMI NDR_NAMED_PIPE_AUTH NDR_TABLE_OBJ_FILES = ../librpc/ndr/ndr_table.o $(gen_ndrsrcdir)/tables.o -- cgit From 7bad4b48c82fed4263c2bfe97a4d00b47913604a Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Wed, 22 Jul 2009 20:15:58 +0200 Subject: [SAMBA 4 / NETLOGON] Modify type of SAM contexts In the SAMBA 4 DCE/RPC NETLOGON server the SAM context references have generally the type "void *". But we know that those context objects are based on the "struct ldb_context" type. We've always to cast for using a SAM/LDB call. This I didn't find very appealing and so I assigned the right (detailed) type to each "sam_ctx". Therefore, the casts could disappear. Also this change is only cosmetic. --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 4d10d961f9..2095bf6fa5 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -151,8 +151,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca } /* pull the user attributes */ - num_records = gendb_search((struct ldb_context *)sam_ctx, - mem_ctx, NULL, &msgs, + num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, trust_dom_attrs, "(&(trustPartner=%s)(objectclass=trustedDomain))", encoded_account); @@ -184,8 +183,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca } /* pull the user attributes */ - num_records = gendb_search((struct ldb_context *)sam_ctx, mem_ctx, - NULL, &msgs, attrs, + num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs, "(&(sAMAccountName=%s)(objectclass=user))", ldb_binary_encode_string(mem_ctx, account_name)); @@ -852,7 +850,7 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C struct netr_GetDcName *r) { const char * const attrs[] = { NULL }; - void *sam_ctx; + struct ldb_context *sam_ctx; struct ldb_message **res; struct ldb_dn *domain_dn; int ret; @@ -865,13 +863,13 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C return WERR_DS_SERVICE_UNAVAILABLE; } - domain_dn = samdb_domain_to_dn((struct ldb_context *)sam_ctx, mem_ctx, + domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx, r->in.domainname); if (domain_dn == NULL) { return WERR_DS_SERVICE_UNAVAILABLE; } - ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, + ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs); if (ret != 1) { return WERR_NO_SUCH_DOMAIN; @@ -1401,7 +1399,7 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce struct netr_DsrEnumerateDomainTrusts *r) { struct netr_DomainTrustList *trusts; - void *sam_ctx; + struct ldb_context *sam_ctx; int ret; struct ldb_message **dom_res; const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL }; @@ -1413,7 +1411,7 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce return WERR_GENERAL_FAILURE; } - ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL, + ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs); if (ret == -1) { return WERR_GENERAL_FAILURE; -- cgit