From 65ae858c1b49efa64c759a914b09204eca14db42 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 24 Oct 2003 13:49:25 +0000 Subject: Add initshutdown pipe commands to rpcclient. Second part of fix to bug #534 (This used to be commit 99f4fa54497ba1c0fc0ba39d51b3ce201a8e6cd2) --- source3/Makefile.in | 9 +++++---- source3/include/ntdomain.h | 1 + source3/include/smb.h | 6 ++++-- source3/rpc_parse/parse_rpc.c | 10 ++++++++++ source3/rpcclient/rpcclient.c | 2 ++ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 8c1c65e865..b0d9be55ec 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -235,7 +235,7 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \ rpc_client/cli_reg.o rpc_client/cli_pipe.o \ rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \ rpc_client/cli_ds.o rpc_client/cli_echo.o \ - rpc_client/cli_epmapper.o + rpc_client/cli_shutdown.o rpc_client/cli_epmapper.o REGOBJS_OBJ = registry/reg_objects.o REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \ @@ -278,8 +278,8 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \ rpc_parse/parse_samr.o rpc_parse/parse_srv.o \ rpc_parse/parse_wks.o rpc_parse/parse_ds.o \ rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \ - rpc_parse/parse_echo.o rpc_parse/parse_epmapper.o \ - $(REGOBJS_OBJ) + rpc_parse/parse_echo.o rpc_parse/parse_shutdown.o \ + rpc_parse/parse_epmapper.o $(REGOBJS_OBJ) RPC_CLIENT_OBJ = rpc_client/cli_pipe.o @@ -448,7 +448,8 @@ RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o \ rpcclient/cmd_dfs.o rpcclient/cmd_reg.o \ rpcclient/display_sec.o rpcclient/cmd_ds.o \ - rpcclient/cmd_echo.o rpcclient/cmd_epmapper.o + rpcclient/cmd_echo.o rpcclient/cmd_shutdown.o \ + rpcclient/cmd_epmapper.o RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 66057424ca..5da6d86410 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -403,5 +403,6 @@ struct acct_info #include "rpc_ds.h" #include "rpc_echo.h" #include "rpc_epmapper.h" +#include "rpc_shutdown.h" #endif /* _NT_DOMAIN_H */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 1e4c48132a..689e6ebe1d 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -194,6 +194,7 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN]; #define PIPE_SPOOLSS "\\PIPE\\spoolss" #define PIPE_NETDFS "\\PIPE\\netdfs" #define PIPE_ECHO "\\PIPE\\rpcecho" +#define PIPE_SHUTDOWN "\\PIPE\\initshutdown" #define PIPE_EPM "\\PIPE\\epmapper" #define PIPE_NETLOGON_PLAIN "\\NETLOGON" @@ -208,8 +209,9 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN]; #define PI_SPOOLSS 7 #define PI_NETDFS 8 #define PI_ECHO 9 -#define PI_EPM 10 -#define PI_MAX_PIPES 11 +#define PI_SHUTDOWN 10 +#define PI_EPM 11 +#define PI_MAX_PIPES 12 /* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */ typedef struct nttime_info diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index f053297192..18ac37778c 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -147,6 +147,15 @@ interface/version dce/rpc pipe identification }, 0x01 \ } +#define SYNT_SHUTDOWN_V1 \ +{ \ + { \ + 0x894de0c0, 0x0d55, 0x11d3, \ + { 0xa3, 0x22, 0x00, 0xc0, \ + 0x4f, 0xa3, 0x21, 0xa1 } \ + }, 0x01 \ +} + #define SYNT_EPM_V3 \ { \ { \ @@ -174,6 +183,7 @@ const struct pipe_id_info pipe_names [] = { PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS , TRANS_SYNT_V2 }, { PIPE_NETDFS , SYNT_NETDFS_V3 , PIPE_NETDFS , TRANS_SYNT_V2 }, { PIPE_ECHO , SYNT_ECHO_V1 , PIPE_ECHO , TRANS_SYNT_V2 }, + { PIPE_SHUTDOWN, SYNT_SHUTDOWN_V1 , PIPE_SHUTDOWN , TRANS_SYNT_V2 }, { PIPE_EPM , SYNT_EPM_V3 , PIPE_EPM , TRANS_SYNT_V2 }, { NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 } }; diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index f60cb67cba..0b60dea2fa 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -462,6 +462,7 @@ extern struct cmd_set dfs_commands[]; extern struct cmd_set reg_commands[]; extern struct cmd_set ds_commands[]; extern struct cmd_set echo_commands[]; +extern struct cmd_set shutdown_commands[]; extern struct cmd_set epm_commands[]; static struct cmd_set *rpcclient_command_list[] = { @@ -475,6 +476,7 @@ static struct cmd_set *rpcclient_command_list[] = { dfs_commands, reg_commands, echo_commands, + shutdown_commands, epm_commands, NULL }; -- cgit From e958f3b50ec172f40c1187ca912c5aba6bb43eca Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 24 Oct 2003 14:03:15 +0000 Subject: Add shutdown abort try over initshutdown pipe first, then fall back to winreg pipe if it doesn't work. Fixes bug #534. I will go back and add the same logic for the shutdown itself, even though that works so far against win2k (haven't tested all win clients). (This used to be commit e6d02117755d92d1b5ce029bf659d0fbe1a55585) --- source3/utils/net_rpc.c | 53 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 85818152d1..298e8ff669 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1461,7 +1461,7 @@ int net_rpc_file(int argc, const char **argv) /** - * ABORT the shutdown of a remote RPC Server + * ABORT the shutdown of a remote RPC Server over, initshutdown pipe * * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passed through. @@ -1476,11 +1476,47 @@ int net_rpc_file(int argc, const char **argv) * @return Normal NTSTATUS return. **/ -static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, +static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, + struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + result = cli_shutdown_abort(cli, mem_ctx); + + if (NT_STATUS_IS_OK(result)) + DEBUG(5,("cmd_shutdown_abort: query succeeded\n")); + else + DEBUG(5,("cmd_shutdown_abort: query failed\n")); + + return result; +} + + +/** + * ABORT the shutdown of a remote RPC Server, over winreg pipe + * + * All parameters are provided by the run_rpc_command function, except for + * argc, argv which are passed through. + * + * @param domain_sid The domain sid aquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on compleation of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ + +static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid, + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + result = cli_reg_abort_shutdown(cli, mem_ctx); if (NT_STATUS_IS_OK(result)) @@ -1491,7 +1527,6 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct c return result; } - /** * ABORT the Shut down of a remote RPC server * @@ -1504,7 +1539,17 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct c static int rpc_shutdown_abort(int argc, const char **argv) { - return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_abort_internals, + int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0, + rpc_shutdown_abort_internals, + argc, argv); + + if (rc == 0) + return rc; + + DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n")); + + return run_rpc_command(NULL, PI_WINREG, 0, + rpc_reg_shutdown_abort_internals, argc, argv); } -- cgit From 99364f1615d86a6aeb9454d40cf596095b78fd1c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 24 Oct 2003 17:50:19 +0000 Subject: Janitorial duty for tpot. Merge tdb error log fix. Jeremy. (This used to be commit 2186cbf28db496b97b39b81eb1932690c6094cd8) --- source3/tdb/tdb.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index e68bda4055..c98b0936ed 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -237,10 +237,15 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, tdb->fd, offset, rw_type, lck_type)); } /* Was it an alarm timeout ? */ - if (errno == EINTR && palarm_fired && *palarm_fired) + if (errno == EINTR && palarm_fired && *palarm_fired) { + TDB_LOG((tdb, 5, "tdb_brlock timed out (fd=%d) at offset %d rw_type=%d lck_type=%d\n", + tdb->fd, offset, rw_type, lck_type)); return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1); + } /* Otherwise - generic lock error. */ /* errno set by fcntl */ + TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n", + tdb->fd, offset, rw_type, lck_type, strerror(errno))); return TDB_ERRCODE(TDB_ERR_LOCK, -1); } return 0; -- cgit From 3f3e3898696eb60b2d91af081ad3e9306efb1801 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 27 Oct 2003 20:09:12 +0000 Subject: Missing UNIX -> DOS codepage conversion. Fix from Alexander Bokovoy . Jeremy. (This used to be commit f714998b44c6a1082943a399ce3b0ce316efc3a0) --- source3/smbd/lanman.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 30934d0b3a..3ea6ab483b 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -2346,15 +2346,15 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par pstring comment; uint32 servertype= lp_default_server_announce(); - pstrcpy(comment,string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH)); + push_ascii(comment,lp_serverstring(), MAX_SERVER_STRING_LENGTH,STR_TERMINATE); if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) { - for (i=0;i Date: Mon, 27 Oct 2003 23:42:38 +0000 Subject: Remove trailing comma on typedef enum. albert chin (china@thewrittenword.com) (This used to be commit 65a4c2aa0af4572ef7da0f7907ee144faba39031) --- source3/rpcclient/rpcclient.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpcclient/rpcclient.h b/source3/rpcclient/rpcclient.h index 1db4246d37..e1e61dc43d 100644 --- a/source3/rpcclient/rpcclient.h +++ b/source3/rpcclient/rpcclient.h @@ -25,7 +25,7 @@ typedef enum { RPC_RTYPE_NTSTATUS = 0, RPC_RTYPE_WERROR, - MAX_RPC_RETURN_TYPE, + MAX_RPC_RETURN_TYPE } RPC_RETURN_TYPE; struct cmd_set { -- cgit From 3638769e02ca8d1ab9cb17d7b10e6e9cdb6ea2e5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Oct 2003 00:51:19 +0000 Subject: Fix for bug #667. DFS filenames can now have arbitrary case. Jeremy. (This used to be commit cbefb5c4f983ca49fcc563111d8704d3770daf81) --- source3/msdfs/msdfs.c | 93 ++++++++++++++++++++--------------------- source3/rpc_server/srv_dfs_nt.c | 58 ++++++++++++++++--------- source3/smbd/trans2.c | 2 +- 3 files changed, 86 insertions(+), 67 deletions(-) diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index 5cc4bf45d6..20814c2ceb 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -78,6 +78,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp) /******************************************************** Fake up a connection struct for the VFS layer. + Note this CHANGES CWD !!!! JRA. *********************************************************/ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path) @@ -99,6 +100,11 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path) talloc_destroy( conn->mem_ctx ); return False; } + if (vfs_ChDir(conn,conn->connectpath) != 0) { + DEBUG(0,("create_conn_struct: Can't ChDir to new conn path %s\n", conn->connectpath)); + talloc_destroy( conn->mem_ctx ); + return False; + } return True; } @@ -161,7 +167,8 @@ static BOOL parse_symlink(char* buf,struct referral** preflist, /********************************************************************** Returns true if the unix path is a valid msdfs symlink **********************************************************************/ -BOOL is_msdfs_link(connection_struct* conn, char* path, + +BOOL is_msdfs_link(connection_struct* conn, char * path, struct referral** reflistp, int* refcnt, SMB_STRUCT_STAT *sbufp) { @@ -172,8 +179,6 @@ BOOL is_msdfs_link(connection_struct* conn, char* path, if (!path || !conn) return False; - strlower_m(path); - if (sbufp == NULL) sbufp = &st; @@ -212,17 +217,21 @@ they request referrals for dfs roots on a server. consumedcntp: how much of the dfs path is being redirected. the client should try the remaining path on the redirected server. + *****************************************************************/ -static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, + +static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp, connection_struct* conn, BOOL findfirst_flag, struct referral** reflistpp, int* refcntp, BOOL* self_referralp, int* consumedcntp) { - fstring localpath; + pstring localpath; int consumed_level = 1; char *p; - fstring reqpath; + BOOL bad_path = False; + SMB_STRUCT_STAT sbuf; + pstring reqpath; if (!dp || !conn) { DEBUG(1,("resolve_dfs_path: NULL dfs_path* or NULL connection_struct*!\n")); @@ -237,10 +246,13 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, return False; } + DEBUG(10,("resolve_dfs_path: Conn path = %s req_path = %s\n", conn->connectpath, dp->reqpath)); + + unix_convert(dp->reqpath,conn,0,&bad_path,&sbuf); + /* JRA... should we strlower the last component here.... ? */ + pstrcpy(localpath, dp->reqpath); + /* check if need to redirect */ - fstrcpy(localpath, conn->connectpath); - fstrcat(localpath, "/"); - fstrcat(localpath, dp->reqpath); if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) { if (findfirst_flag) { DEBUG(6,("resolve_dfs_path (FindFirst) No redirection " @@ -256,13 +268,11 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, } /* redirect if any component in the path is a link */ - fstrcpy(reqpath, dp->reqpath); + pstrcpy(reqpath, dp->reqpath); p = strrchr(reqpath, '/'); while (p) { *p = '\0'; - fstrcpy(localpath, conn->connectpath); - fstrcat(localpath, "/"); - fstrcat(localpath, reqpath); + pstrcpy(localpath, reqpath); if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) { DEBUG(4, ("resolve_dfs_path: Redirecting %s because parent %s is dfs link\n", dfspath, localpath)); @@ -278,7 +288,8 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, trim_char(buf, '\0', '\\'); for (; consumed_level; consumed_level--) { q = strrchr(buf, '\\'); - if (q) *q = 0; + if (q) + *q = 0; } *consumedcntp = strlen(buf); DEBUG(10, ("resolve_dfs_path: Path consumed: %s (%d)\n", buf, *consumedcntp)); @@ -297,7 +308,8 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, Decides if a dfs pathname should be redirected or not. If not, the pathname is converted to a tcon-relative local unix path *****************************************************************/ -BOOL dfs_redirect(char* pathname, connection_struct* conn, + +BOOL dfs_redirect(pstring pathname, connection_struct* conn, BOOL findfirst_flag) { struct dfs_path dp; @@ -310,7 +322,7 @@ BOOL dfs_redirect(char* pathname, connection_struct* conn, /* if dfs pathname for a non-dfs share, convert to tcon-relative path and return false */ if (!lp_msdfs_root(SNUM(conn))) { - fstrcpy(pathname, dp.reqpath); + pstrcpy(pathname, dp.reqpath); return False; } @@ -325,7 +337,7 @@ BOOL dfs_redirect(char* pathname, connection_struct* conn, DEBUG(3,("dfs_redirect: Not redirecting %s.\n", pathname)); /* Form non-dfs tcon-relative path */ - fstrcpy(pathname, dp.reqpath); + pstrcpy(pathname, dp.reqpath); DEBUG(3,("dfs_redirect: Path converted to non-dfs path %s\n", pathname)); return False; @@ -338,6 +350,7 @@ BOOL dfs_redirect(char* pathname, connection_struct* conn, Gets valid referrals for a dfs path and fills up the junction_map structure **********************************************************************/ + BOOL get_referred_path(char *pathname, struct junction_map* jn, int* consumedcntp, BOOL* self_referralp) { @@ -363,14 +376,12 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, /* Verify hostname in path */ if (local_machine && (!strequal(local_machine, dp.hostname))) { - - /* Hostname mismatch, check if one of our IP addresses */ - if (!ismyip(*interpret_addr2(dp.hostname))) { - - DEBUG(3, ("get_referred_path: Invalid hostname %s in path %s\n", - dp.hostname, pathname)); - return False; - } + /* Hostname mismatch, check if one of our IP addresses */ + if (!ismyip(*interpret_addr2(dp.hostname))) { + DEBUG(3, ("get_referred_path: Invalid hostname %s in path %s\n", + dp.hostname, pathname)); + return False; + } } pstrcpy(jn->service_name, dp.servicename); @@ -386,7 +397,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, pstrcpy(conn_path, lp_pathname(snum)); if (!create_conn_struct(conn, snum, conn_path)) return False; - + if (!lp_msdfs_root(SNUM(conn))) { DEBUG(3,("get_referred_path: .%s. in dfs path %s is not a dfs root.\n", dp.servicename, pathname)); @@ -626,7 +637,7 @@ static int setup_ver3_dfs_referral(char* pathname, char** ppdata, * Set up the Dfs referral for the dfs pathname ******************************************************************/ -int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata) +int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_referral_level, char** ppdata) { struct junction_map junction; int consumedcnt; @@ -648,12 +659,14 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata) pathnamep++; pstrcpy(buf, pathnamep); - if (!get_referred_path(buf, &junction, &consumedcnt, - &self_referral)) + /* The following call can change cwd. */ + if (!get_referred_path(buf, &junction, &consumedcnt, &self_referral)) { + vfs_ChDir(orig_conn,orig_conn->connectpath); return -1; + } + vfs_ChDir(orig_conn,orig_conn->connectpath); - if (!self_referral) - { + if (!self_referral) { pathnamep[consumedcnt] = '\0'; if( DEBUGLVL( 3 ) ) { @@ -672,24 +685,18 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata) switch(max_referral_level) { case 2: - { reply_size = setup_ver2_dfs_referral(pathnamep, ppdata, &junction, consumedcnt, self_referral); SAFE_FREE(junction.referral_list); break; - } case 3: - { reply_size = setup_ver3_dfs_referral(pathnamep, ppdata, &junction, consumedcnt, self_referral); SAFE_FREE(junction.referral_list); break; - } default: - { DEBUG(0,("setup_dfs_referral: Invalid dfs referral version: %d\n", max_referral_level)); return -1; - } } DEBUG(10,("DFS Referral pdata:\n")); @@ -752,7 +759,6 @@ static BOOL junction_to_local_path(struct junction_map* jn, char* path, safe_strcpy(path, lp_pathname(snum), max_pathlen-1); safe_strcat(path, "/", max_pathlen-1); - strlower_m(jn->volume_name); safe_strcat(path, jn->volume_name, max_pathlen-1); pstrcpy(conn_path, lp_pathname(snum)); @@ -885,18 +891,12 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count) cnt++; /* Now enumerate all dfs links */ - dirp = SMB_VFS_OPENDIR(conn, connect_path); + dirp = SMB_VFS_OPENDIR(conn, "."); if(!dirp) goto out; while((dname = vfs_readdirname(conn, dirp)) != NULL) { - pstring pathreal; - - pstrcpy(pathreal, connect_path); - pstrcat(pathreal, "/"); - pstrcat(pathreal, dname); - - if (is_msdfs_link(conn, pathreal, &(jn[cnt].referral_list), + if (is_msdfs_link(conn, dname, &(jn[cnt].referral_list), &(jn[cnt].referral_count), NULL)) { pstrcpy(jn[cnt].service_name, service_name); pstrcpy(jn[cnt].volume_name, dname); @@ -925,4 +925,3 @@ int enum_msdfs_links(struct junction_map* jn) } return jn_count; } - diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c index 751cb6e642..ac3ed9c394 100644 --- a/source3/rpc_server/srv_dfs_nt.c +++ b/source3/rpc_server/srv_dfs_nt.c @@ -70,6 +70,7 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u) pstrcat(altpath, "\\"); pstrcat(altpath, sharename); + /* The following call can change the cwd. */ if(get_referred_path(dfspath, &jn, NULL, NULL)) { exists = True; @@ -79,6 +80,8 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u) else jn.referral_count = 1; + vfs_ChDir(p->conn,p->conn->connectpath); + jn.referral_list = (struct referral*) talloc(p->mem_ctx, jn.referral_count * sizeof(struct referral)); @@ -100,8 +103,11 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u) pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath); - if(!create_msdfs_link(&jn, exists)) + if(!create_msdfs_link(&jn, exists)) { + vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_CANT_CREATE_JUNCT; + } + vfs_ChDir(p->conn,p->conn->connectpath); return WERR_OK; } @@ -147,8 +153,11 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, /* if no server-share pair given, remove the msdfs link completely */ if(!q_u->ptr_ServerName && !q_u->ptr_ShareName) { - if(!remove_msdfs_link(&jn)) + if(!remove_msdfs_link(&jn)) { + vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_NO_SUCH_VOL; + } + vfs_ChDir(p->conn,p->conn->connectpath); } else { @@ -175,13 +184,19 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, /* Only one referral, remove it */ if(jn.referral_count == 1) { - if(!remove_msdfs_link(&jn)) + if(!remove_msdfs_link(&jn)) { + vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_NO_SUCH_VOL; + } + vfs_ChDir(p->conn,p->conn->connectpath); } else { - if(!create_msdfs_link(&jn, True)) + if(!create_msdfs_link(&jn, True)) { + vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_CANT_CREATE_JUNCT; + } + vfs_ChDir(p->conn,p->conn->connectpath); } } @@ -325,7 +340,8 @@ WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u) int num_jn = 0; num_jn = enum_msdfs_links(jn); - + vfs_ChDir(p->conn,p->conn->connectpath); + DEBUG(5,("make_reply_dfs_enum: %d junctions found in Dfs, doing level %d\n", num_jn, level)); r_u->ptr_buffer = level; @@ -351,21 +367,25 @@ WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u) WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, DFS_R_DFS_GET_INFO *r_u) { - UNISTR2* uni_path = &q_u->uni_path; - uint32 level = q_u->level; - pstring path; - struct junction_map jn; - - unistr2_to_ascii(path, uni_path, sizeof(path)-1); - if(!create_junction(path, &jn)) - return WERR_DFS_NO_SUCH_SERVER; + UNISTR2* uni_path = &q_u->uni_path; + uint32 level = q_u->level; + pstring path; + struct junction_map jn; + + unistr2_to_ascii(path, uni_path, sizeof(path)-1); + if(!create_junction(path, &jn)) + return WERR_DFS_NO_SUCH_SERVER; - if(!get_referred_path(path, &jn, NULL, NULL)) - return WERR_DFS_NO_SUCH_VOL; + /* The following call can change the cwd. */ + if(!get_referred_path(path, &jn, NULL, NULL)) { + vfs_ChDir(p->conn,p->conn->connectpath); + return WERR_DFS_NO_SUCH_VOL; + } - r_u->level = level; - r_u->ptr_ctr = 1; - r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, &r_u->ctr, &jn, 1); + vfs_ChDir(p->conn,p->conn->connectpath); + r_u->level = level; + r_u->ptr_ctr = 1; + r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, &r_u->ctr, &jn, 1); - return r_u->status; + return r_u->status; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 0f02403184..5677fb9a41 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3297,7 +3297,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE); - if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0) + if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0) return ERROR_DOS(ERRDOS,ERRbadfile); SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES); -- cgit From e893948e04136ed5b9ba08373a93dd55f81e2e24 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Oct 2003 18:32:01 +0000 Subject: Don't log at level zero when chdir fails. Ensure correct error message is returned. Jeremy. (This used to be commit a7561336e770405572c13a4607b0e808225e8916) --- source3/msdfs/msdfs.c | 3 ++- source3/smbd/trans2.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index 20814c2ceb..ce29c506bb 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -101,7 +101,8 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path) return False; } if (vfs_ChDir(conn,conn->connectpath) != 0) { - DEBUG(0,("create_conn_struct: Can't ChDir to new conn path %s\n", conn->connectpath)); + DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. Error was %s\n", + conn->connectpath, strerror(errno) )); talloc_destroy( conn->mem_ctx ); return False; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 5677fb9a41..394adeeb6f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3298,7 +3298,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE); if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0) - return ERROR_DOS(ERRDOS,ERRbadfile); + return UNIXERROR(ERRDOS,ERRbadfile); SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES); send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size); -- cgit From 5ca824a682bbcd9331f32935f9b423ae6d468816 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Oct 2003 21:27:57 +0000 Subject: Fixes to check for wraps which could cause coredumps. Jeremy. (This used to be commit 124a8ddae63adff4f601242a8e6d05abcaf4d9bf) --- source3/lib/smbldap.c | 1 + source3/libsmb/clilist.c | 2 +- source3/libsmb/ntlmssp_parse.c | 7 +++---- source3/nmbd/nmbd_processlogon.c | 3 +++ source3/printing/nt_printing.c | 19 ++++++++++++++----- source3/smbd/reply.c | 10 ++++++---- 6 files changed, 28 insertions(+), 14 deletions(-) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 8f58e80dde..fe34cfb852 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -258,6 +258,7 @@ BOOL fetch_ldap_pw(char **dn, char** pw) return False; } + size = MIN(size, sizeof(fstring)-1); strncpy(old_style_pw, data, size); old_style_pw[size] = 0; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 7822987ada..2c1831ae99 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -82,7 +82,7 @@ static int interpret_long_filename(struct cli_state *cli, case 260: /* NT uses this, but also accepts 2 */ { - int namelen, slen; + size_t namelen, slen; p += 4; /* next entry offset */ p += 4; /* fileindex */ diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 60cb4ab04a..b136dacf5a 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -226,7 +226,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, *ps = smb_xstrdup(""); } else { /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } if (len1 & 1) { @@ -255,7 +255,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if (len1 == 0 && len2 == 0) { *ps = smb_xstrdup(""); } else { - if (len1 != len2 || ptr + len1 > blob->length) { + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } @@ -280,7 +280,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, *b = data_blob(NULL, 0); } else { /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } *b = data_blob(blob->data + ptr, len1); @@ -314,4 +314,3 @@ BOOL msrpc_parse(const DATA_BLOB *blob, return True; } - diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index 2a6a6b66d1..816b351464 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -491,6 +491,8 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", /* Domain SID */ +#if 0 + /* We must range check this. */ q += IVAL(q, 0) + 4; /* 4 byte length plus data */ q += 2; /* Alignment? */ @@ -500,6 +502,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", q += 4; /* NT version (0x1) */ q += 2; /* LMNT token (0xff) */ q += 2; /* LM20 token (0xff) */ +#endif SAFE_FREE(db_info); /* Not sure whether we need to do anything useful with these */ diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 5b5b5885ab..908bd9c887 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -728,7 +728,7 @@ const char *get_short_archi(const char *long_archi) static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor) { int i; - char *buf; + char *buf = NULL; ssize_t byte_count; if ((buf=malloc(PE_HEADER_SIZE)) == NULL) { @@ -768,8 +768,8 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 /* The header may be a PE (Portable Executable) or an NE (New Executable) */ if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) { - int num_sections; - int section_table_bytes; + unsigned int num_sections; + unsigned int section_table_bytes; if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) { DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n", @@ -783,6 +783,9 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 /* get the section table */ num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS); section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE; + if (section_table_bytes == 0) + goto error_exit; + SAFE_FREE(buf); if ((buf=malloc(section_table_bytes)) == NULL) { DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n", @@ -801,8 +804,11 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE; if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) { - int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET); - int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET); + unsigned int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET); + unsigned int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET); + + if (section_bytes == 0) + goto error_exit; SAFE_FREE(buf); if ((buf=malloc(section_bytes)) == NULL) { @@ -824,6 +830,9 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 goto error_exit; } + if (section_bytes < VS_VERSION_INFO_UNICODE_SIZE) + goto error_exit; + for (i=0; i dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn)))); if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True)) @@ -845,7 +847,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size if ((! *directory) && dptr_path(dptr_num)) slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); - DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n", + DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n", smb_fn_name(CVAL(inbuf,smb_com)), mask, directory, dirtype, numentries, maxentries ) ); -- cgit From 5a1515f453cf4bc2f013c8751336e403637875c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Oct 2003 23:01:02 +0000 Subject: Janitor for tridge. parameterise the listen backlog in smbd and make it larger by default. A backlog of 5 is way too small these days. Jeremy. (This used to be commit 58b8f673945ad114d056dd79f509c93ab42b96d1) --- source3/include/local.h | 3 +++ source3/smbd/server.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/source3/include/local.h b/source3/include/local.h index 4c3c58e14f..540365047a 100644 --- a/source3/include/local.h +++ b/source3/include/local.h @@ -227,4 +227,7 @@ /* Buffer size to use when printing backtraces */ #define BACKTRACE_STACK_SIZE 64 +/* size of listen() backlog in smbd */ +#define SMBD_LISTEN_BACKLOG 50 + #endif diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 8b890549ea..af39bcb757 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -250,7 +250,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ set_socket_options(s,"SO_KEEPALIVE"); set_socket_options(s,user_socket_options); - if (listen(s, 5) == -1) { + if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { DEBUG(0,("listen: %s\n",strerror(errno))); close(s); return False; @@ -286,7 +286,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ set_socket_options(s,"SO_KEEPALIVE"); set_socket_options(s,user_socket_options); - if (listen(s, 5) == -1) { + if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { DEBUG(0,("open_sockets_smbd: listen: %s\n", strerror(errno))); close(s); -- cgit From bc3ab60c96dc125ed913503d14a66923dd7cee72 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 30 Oct 2003 00:07:46 +0000 Subject: Check for nsswitch.h. Patch from albert chin (china@thewrittenword.com). Jeremy. (This used to be commit 8d29faaa6396a46e8754ead32f6fd545e567ba46) --- source3/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index bbf26c916d..f0a2c3c3f3 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -591,7 +591,7 @@ case "$host_os" in ;; esac AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h) -AC_CHECK_HEADERS(nss.h nss_common.h ns_api.h sys/security.h security/pam_appl.h security/pam_modules.h) +AC_CHECK_HEADERS(nss.h nss_common.h nsswitch.h ns_api.h sys/security.h security/pam_appl.h security/pam_modules.h) AC_CHECK_HEADERS(stropts.h poll.h) AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h) AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/cdefs.h glob.h) -- cgit From 11e6f4b5185f6d3ee4e8c91cf598839a7f1d5002 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 30 Oct 2003 16:01:02 +0000 Subject: bug 696; check for an invalid fid before dereferencing the fsp pointer (This used to be commit 2cc43e760b02f2088a0222d1f5080913a96f3e5a) --- source3/smbd/trans2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 394adeeb6f..56d1aae3a2 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3319,7 +3319,12 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, { char *pdata = *ppdata; files_struct *fsp = file_fsp(inbuf,smb_vwv15); + + /* check for an invalid fid before proceeding */ + if (!fsp) + return(ERROR_DOS(ERRDOS,ERRbadfid)); + if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) && (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) { pdata = Realloc(*ppdata, 32); -- cgit From 523444b7b69fd14798a70cbf98b4f5f0177bfd2a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 30 Oct 2003 16:38:39 +0000 Subject: First round of merging various UUID structures. This eliminates RPC_UUID. It creates the following struct: struct uuid { uint32 time_low; uint16 time_mid; uint16 time_hi_and_version; uint8 clock_seq[2]; uint8 node[6]; }; which replaces RPC_UUID and various random struct uuid definitions and a flat version: #define UUID_FLAT_SIZE 16 typedef struct uuid_flat { uint8 info[UUID_FLAT_SIZE]; } UUID_FLAT; which pretty much looks like GUID (which I will start eliminating). I want us to use the FLAT one only on the wire (perhaps in files, too?), and I want it to be obvious to the coder that it is the FLAT version. This leaves a couple of compiler warnings, where GUID isn't completely replaced by FLAT_UUID yet...I'll get to those soon. (This used to be commit 1532b5d2e3c61df232b16394acedf6eac387588b) --- source3/include/ntdomain.h | 16 +++++++ source3/include/rpc_dce.h | 18 +------- source3/include/rpc_ds.h | 4 +- source3/include/rpc_epmapper.h | 2 +- source3/lib/util_sid.c | 17 -------- source3/lib/util_uuid.c | 64 ++++++++++++---------------- source3/libads/ldap.c | 12 ++---- source3/passdb/secrets.c | 21 +++++---- source3/rpc_parse/parse_ds.c | 6 +-- source3/rpc_parse/parse_epmapper.c | 6 +-- source3/rpc_parse/parse_rpc.c | 82 ++++++++++++++++++++++-------------- source3/rpc_server/srv_epmapper_nt.c | 2 +- source3/rpc_server/srv_pipe.c | 4 +- source3/rpc_server/srv_spoolss_nt.c | 5 ++- source3/rpcclient/cmd_epmapper.c | 18 ++++---- source3/rpcclient/cmd_lsarpc.c | 7 +-- source3/utils/net_ads_cldap.c | 10 ++--- 17 files changed, 141 insertions(+), 153 deletions(-) diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 5da6d86410..d9fff4d2a9 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -23,6 +23,22 @@ #ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */ #define _NT_DOMAIN_H +struct uuid +{ + uint32 time_low; + uint16 time_mid; + uint16 time_hi_and_version; + uint8 clock_seq[2]; + uint8 node[6]; +}; +#define UUID_SIZE 16 + +#define UUID_FLAT_SIZE 16 +typedef struct uuid_flat +{ + uint8 info[UUID_FLAT_SIZE]; +} UUID_FLAT; + /* dce/rpc support */ #include "rpc_dce.h" diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h index 52fe08d875..8266fc861f 100644 --- a/source3/include/rpc_dce.h +++ b/source3/include/rpc_dce.h @@ -87,29 +87,15 @@ enum netsec_direction /* #define MAX_PDU_FRAG_LEN 0x1630 this is what wnt sets */ #define MAX_PDU_FRAG_LEN 0x10b8 /* this is what w2k sets */ -/* - * Actual structure of a DCE UUID - */ - -typedef struct rpc_uuid -{ - uint32 time_low; - uint16 time_mid; - uint16 time_hi_and_version; - uint8 remaining[8]; -} RPC_UUID; - -#define RPC_UUID_LEN 16 - /* RPC_IFACE */ typedef struct rpc_iface_info { - RPC_UUID uuid; /* 16 bytes of rpc interface identification */ + struct uuid uuid; /* 16 bytes of rpc interface identification */ uint32 version; /* the interface version number */ } RPC_IFACE; -#define RPC_IFACE_LEN (RPC_UUID_LEN + 4) +#define RPC_IFACE_LEN (UUID_SIZE + 4) struct pipe_id_info { diff --git a/source3/include/rpc_ds.h b/source3/include/rpc_ds.h index e2622be532..4d3f5416ac 100644 --- a/source3/include/rpc_ds.h +++ b/source3/include/rpc_ds.h @@ -64,7 +64,7 @@ typedef struct uint32 dnsname_ptr; uint32 forestname_ptr; - GUID domain_guid; + struct uuid domain_guid; UNISTR2 netbios_domain; @@ -110,7 +110,7 @@ typedef struct { uint32 trust_type; uint32 trust_attributes; uint32 sid_ptr; - GUID guid; + struct uuid guid; UNISTR2 netbios_domain; UNISTR2 dns_domain; diff --git a/source3/include/rpc_epmapper.h b/source3/include/rpc_epmapper.h index de3a2cb08d..bbca6ac1f2 100644 --- a/source3/include/rpc_epmapper.h +++ b/source3/include/rpc_epmapper.h @@ -51,7 +51,7 @@ typedef struct uint16 length; uint8 protocol; struct { - RPC_UUID uuid; + struct uuid uuid; uint16 version; } uuid; } lhs; diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 50bbb4c72c..2c0bd79785 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -617,23 +617,6 @@ char *sid_binstring(const DOM_SID *sid) return s; } - -/***************************************************************** - Print a GUID structure for debugging. -*****************************************************************/ - -void print_guid(GUID *guid) -{ - int i; - - d_printf("%08x-%04x-%04x", - IVAL(guid->info, 0), SVAL(guid->info, 4), SVAL(guid->info, 6)); - d_printf("-%02x%02x-", guid->info[8], guid->info[9]); - for (i=10;iinfo[i]); - d_printf("\n"); -} - /******************************************************************* Tallocs a duplicate SID. ********************************************************************/ diff --git a/source3/lib/util_uuid.c b/source3/lib/util_uuid.c index 56f0ecd85b..8217006e58 100644 --- a/source3/lib/util_uuid.c +++ b/source3/lib/util_uuid.c @@ -27,57 +27,47 @@ #define TIME_OFFSET_HIGH 0x01B21DD2 #define TIME_OFFSET_LOW 0x13814000 -struct uuid { - uint32 time_low; - uint16 time_mid; - uint16 time_hi_and_version; - uint8 clock_seq[2]; - uint8 node[6]; -}; - - -static void uuid_pack(const struct uuid *uu, GUID *ptr) +void smb_uuid_pack(const struct uuid *uu, UUID_FLAT *ptr) { - uint8 *out = ptr->info; + SIVAL(ptr, 0, uu->time_low); + SSVAL(ptr, 4, uu->time_mid); + SSVAL(ptr, 6, uu->time_hi_and_version); + memcpy(ptr+8, uu->clock_seq, 2); + memcpy(ptr+10, uu->node, 6); +} - SIVAL(out, 0, uu->time_low); - SSVAL(out, 4, uu->time_mid); - SSVAL(out, 6, uu->time_hi_and_version); - memcpy(out+8, uu->clock_seq, 2); - memcpy(out+10, uu->node, 6); +void smb_uuid_unpack(const UUID_FLAT in, struct uuid *uu) +{ + uu->time_low = IVAL(in.info, 0); + uu->time_mid = SVAL(in.info, 4); + uu->time_hi_and_version = SVAL(in.info, 6); + memcpy(uu->clock_seq, in.info+8, 2); + memcpy(uu->node, in.info+10, 6); } -static void uuid_unpack(const GUID in, struct uuid *uu) +const struct uuid smb_uuid_unpack_static(const UUID_FLAT in) { - const uint8 *ptr = in.info; + static struct uuid uu; - uu->time_low = IVAL(ptr, 0); - uu->time_mid = SVAL(ptr, 4); - uu->time_hi_and_version = SVAL(ptr, 6); - memcpy(uu->clock_seq, ptr+8, 2); - memcpy(uu->node, ptr+10, 6); + smb_uuid_unpack(in, &uu); + return uu; } -void smb_uuid_generate_random(GUID *out) +void smb_uuid_generate_random(struct uuid *uu) { - GUID tmp; - struct uuid uu; + UUID_FLAT tmp; generate_random_buffer(tmp.info, sizeof(tmp.info), True); - uuid_unpack(tmp, &uu); + smb_uuid_unpack(tmp, uu); - uu.clock_seq[0] = (uu.clock_seq[0] & 0x3F) | 0x80; - uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000; - uuid_pack(&uu, out); + uu->clock_seq[0] = (uu->clock_seq[0] & 0x3F) | 0x80; + uu->time_hi_and_version = (uu->time_hi_and_version & 0x0FFF) | 0x4000; } -char *smb_uuid_to_string(const GUID in) +char *smb_uuid_to_string(const struct uuid uu) { - struct uuid uu; char *out; - uuid_unpack(in, &uu); - asprintf(&out, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", uu.time_low, uu.time_mid, uu.time_hi_and_version, uu.clock_seq[0], uu.clock_seq[1], @@ -87,13 +77,11 @@ char *smb_uuid_to_string(const GUID in) return out; } -const char *smb_uuid_string_static(const GUID in) +const char *smb_uuid_string_static(const struct uuid uu) { - struct uuid uu; static char out[37]; - uuid_unpack(in, &uu); - slprintf(out, sizeof(out) -1, + slprintf(out, sizeof(out), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", uu.time_low, uu.time_mid, uu.time_hi_and_version, uu.clock_seq[0], uu.clock_seq[1], diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b3706cb240..ed26bf07f2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1091,20 +1091,14 @@ static void dump_binary(const char *field, struct berval **values) } } -struct uuid { - uint32 i1; - uint16 i2; - uint16 i3; - uint8 s[8]; -}; - static void dump_guid(const char *field, struct berval **values) { int i; - GUID guid; + UUID_FLAT guid; for (i=0; values[i]; i++) { memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); - printf("%s: %s\n", field, smb_uuid_string_static(guid)); + printf("%s: %s\n", field, + smb_uuid_string_static(smb_uuid_unpack_static(guid))); } } diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 8a146f0d68..a5a2c29a8b 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -128,39 +128,38 @@ BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid) return True; } -BOOL secrets_store_domain_guid(const char *domain, GUID *guid) +BOOL secrets_store_domain_guid(const char *domain, struct uuid *guid) { fstring key; slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain); strupper_m(key); - return secrets_store(key, guid, sizeof(GUID)); + return secrets_store(key, guid, sizeof(struct uuid)); } -BOOL secrets_fetch_domain_guid(const char *domain, GUID *guid) +BOOL secrets_fetch_domain_guid(const char *domain, struct uuid *guid) { - GUID *dyn_guid; + struct uuid *dyn_guid; fstring key; size_t size; - GUID new_guid; + struct uuid new_guid; slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain); strupper_m(key); - dyn_guid = (GUID *)secrets_fetch(key, &size); + dyn_guid = (struct uuid *)secrets_fetch(key, &size); - DEBUG(6,("key is %s, size is %d\n", key, (int)size)); - - if ((NULL == dyn_guid) && (ROLE_DOMAIN_PDC == lp_server_role())) { + if ((!dyn_guid) && (lp_server_role() == ROLE_DOMAIN_PDC)) { smb_uuid_generate_random(&new_guid); if (!secrets_store_domain_guid(domain, &new_guid)) return False; - dyn_guid = (GUID *)secrets_fetch(key, &size); + dyn_guid = (struct uuid *)secrets_fetch(key, &size); if (dyn_guid == NULL) return False; } - if (size != sizeof(GUID)) + if (size != sizeof(struct uuid)) { + DEBUG(1,("UUID size %d is wrong!\n", (int)size)); SAFE_FREE(dyn_guid); return False; } diff --git a/source3/rpc_parse/parse_ds.c b/source3/rpc_parse/parse_ds.c index 26dcdb34b8..8d894b6c6a 100644 --- a/source3/rpc_parse/parse_ds.c +++ b/source3/rpc_parse/parse_ds.c @@ -48,8 +48,8 @@ static BOOL ds_io_dominfobasic( const char *desc, prs_struct *ps, int depth, DSR return False; if ( !prs_uint32("forestname_ptr", ps, depth, &p->forestname_ptr) ) return False; - - if ( !prs_uint8s(False, "domain_guid", ps, depth, p->domain_guid.info, GUID_SIZE) ) + + if ( !smb_io_uuid("domain_guid", &p->domain_guid, ps, depth) ) return False; if ( !smb_io_unistr2( "netbios_domain", &p->netbios_domain, p->netbios_ptr, ps, depth) ) @@ -179,7 +179,7 @@ static BOOL ds_io_domain_trusts( const char *desc, prs_struct *ps, int depth, DS if ( !prs_uint32( "sid_ptr", ps, depth, &trust->sid_ptr ) ) return False; - if ( !prs_uint8s(False, "guid", ps, depth, trust->guid.info, GUID_SIZE) ) + if ( !smb_io_uuid("guid", &trust->guid, ps, depth) ) return False; return True; diff --git a/source3/rpc_parse/parse_epmapper.c b/source3/rpc_parse/parse_epmapper.c index 7a5f147c50..89dc0994c6 100644 --- a/source3/rpc_parse/parse_epmapper.c +++ b/source3/rpc_parse/parse_epmapper.c @@ -88,9 +88,9 @@ NTSTATUS init_epm_floor(EPM_FLOOR *floor, uint8 protocol) inits an EPM_FLOOR structure with a UUID ********************************************************************/ NTSTATUS init_epm_floor_uuid(EPM_FLOOR *floor, - const RPC_UUID *uuid, uint16 version) + const struct uuid uuid, uint16 version) { - memcpy(&floor->lhs.uuid.uuid, uuid, sizeof(*uuid)); + memcpy(&floor->lhs.uuid.uuid, &uuid, sizeof(uuid)); floor->lhs.uuid.version = version; floor->rhs.unknown = 0; return init_epm_floor(floor, EPM_FLOOR_UUID); @@ -166,7 +166,7 @@ BOOL epm_io_floor(const char *desc, EPM_FLOOR *floor, switch (floor->lhs.protocol) { case EPM_FLOOR_UUID: - if (!smb_io_rpc_uuid("uuid", &floor->lhs.uuid.uuid, ps, depth)) + if (!smb_io_uuid("uuid", &floor->lhs.uuid.uuid, ps, depth)) return False; if (!prs_uint16("version", ps, depth, &floor->lhs.uuid.version)) diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index 18ac37778c..1718841cf7 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -34,8 +34,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x8a885d04, 0x1ceb, 0x11c9, \ - { 0x9f, 0xe8, 0x08, 0x00, \ - 0x2b, 0x10, 0x48, 0x60 } \ + { 0x9f, 0xe8 }, \ + { 0x08, 0x00, \ + 0x2b, 0x10, 0x48, 0x60 } \ }, 0x02 \ } @@ -43,8 +44,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x8a885d04, 0x1ceb, 0x11c9, \ - { 0x9f, 0xe8, 0x08, 0x00, \ - 0x2b, 0x10, 0x48, 0x60 } \ + { 0x9f, 0xe8 }, \ + { 0x08, 0x00, \ + 0x2b, 0x10, 0x48, 0x60 } \ }, 0x02 \ } @@ -52,8 +54,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x6bffd098, 0xa112, 0x3610, \ - { 0x98, 0x33, 0x46, 0xc3, \ - 0xf8, 0x7e, 0x34, 0x5a } \ + { 0x98, 0x33 }, \ + { 0x46, 0xc3, \ + 0xf8, 0x7e, 0x34, 0x5a } \ }, 0x01 \ } @@ -61,8 +64,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x4b324fc8, 0x1670, 0x01d3, \ - { 0x12, 0x78, 0x5a, 0x47, \ - 0xbf, 0x6e, 0xe1, 0x88 } \ + { 0x12, 0x78 }, \ + { 0x5a, 0x47, \ + 0xbf, 0x6e, 0xe1, 0x88 } \ }, 0x03 \ } @@ -70,8 +74,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x12345778, 0x1234, 0xabcd, \ - { 0xef, 0x00, 0x01, 0x23, \ - 0x45, 0x67, 0x89, 0xab } \ + { 0xef, 0x00 }, \ + { 0x01, 0x23, \ + 0x45, 0x67, 0x89, 0xab } \ }, 0x00 \ } @@ -79,8 +84,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x3919286a, 0xb10c, 0x11d0, \ - { 0x9b, 0xa8, 0x00, 0xc0, \ - 0x4f, 0xd9, 0x2e, 0xf5 } \ + { 0x9b, 0xa8 }, \ + { 0x00, 0xc0, \ + 0x4f, 0xd9, 0x2e, 0xf5 } \ }, 0x00 \ } @@ -88,8 +94,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x12345778, 0x1234, 0xabcd, \ - { 0xef, 0x00, 0x01, 0x23, \ - 0x45, 0x67, 0x89, 0xac } \ + { 0xef, 0x00 }, \ + { 0x01, 0x23, \ + 0x45, 0x67, 0x89, 0xac } \ }, 0x01 \ } @@ -97,8 +104,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x12345678, 0x1234, 0xabcd, \ - { 0xef, 0x00, 0x01, 0x23, \ - 0x45, 0x67, 0xcf, 0xfb } \ + { 0xef, 0x00 }, \ + { 0x01, 0x23, \ + 0x45, 0x67, 0xcf, 0xfb } \ }, 0x01 \ } @@ -106,8 +114,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x338cd001, 0x2244, 0x31f1, \ - { 0xaa, 0xaa, 0x90, 0x00, \ - 0x38, 0x00, 0x10, 0x03 } \ + { 0xaa, 0xaa }, \ + { 0x90, 0x00, \ + 0x38, 0x00, 0x10, 0x03 } \ }, 0x01 \ } @@ -115,8 +124,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x12345678, 0x1234, 0xabcd, \ - { 0xef, 0x00, 0x01, 0x23, \ - 0x45, 0x67, 0x89, 0xab } \ + { 0xef, 0x00 }, \ + { 0x01, 0x23, \ + 0x45, 0x67, 0x89, 0xab } \ }, 0x01 \ } @@ -124,8 +134,9 @@ interface/version dce/rpc pipe identification { \ { \ 0x0, 0x0, 0x0, \ - { 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00 } \ + { 0x00, 0x00 }, \ + { 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00 } \ }, 0x00 \ } @@ -133,7 +144,8 @@ interface/version dce/rpc pipe identification { \ { \ 0x4fc742e0, 0x4a10, 0x11cf, \ - { 0x82, 0x73, 0x00, 0xaa, \ + { 0x82, 0x73 }, \ + { 0x00, 0xaa, \ 0x00, 0x4a, 0xe6, 0x73 } \ }, 0x03 \ } @@ -142,7 +154,8 @@ interface/version dce/rpc pipe identification { \ { \ 0x60a15ec5, 0x4de8, 0x11d7, \ - { 0xa6, 0x37, 0x00, 0x50, \ + { 0xa6, 0x37 }, \ + { 0x00, 0x50, \ 0x56, 0xa2, 0x01, 0x82 } \ }, 0x01 \ } @@ -151,7 +164,8 @@ interface/version dce/rpc pipe identification { \ { \ 0x894de0c0, 0x0d55, 0x11d3, \ - { 0xa3, 0x22, 0x00, 0xc0, \ + { 0xa3, 0x22 }, \ + { 0x00, 0xc0, \ 0x4f, 0xa3, 0x21, 0xa1 } \ }, 0x01 \ } @@ -160,8 +174,9 @@ interface/version dce/rpc pipe identification { \ { \ 0xe1af8308, 0x5d1f, 0x11c9, \ - { 0x91, 0xa4, 0x08, 0x00, \ - 0x2b, 0x14, 0xa0, 0xfa } \ + { 0x91, 0xa4 }, \ + { 0x08, 0x00, \ + 0x2b, 0x14, 0xa0, 0xfa } \ }, 0x03 \ } @@ -263,15 +278,16 @@ BOOL smb_io_rpc_hdr(const char *desc, RPC_HDR *rpc, prs_struct *ps, int depth) } /******************************************************************* - Reads or writes an RPC_UUID structure. + Reads or writes a struct uuid ********************************************************************/ -BOOL smb_io_rpc_uuid(const char *desc, RPC_UUID *uuid, prs_struct *ps, int depth) +BOOL smb_io_uuid(const char *desc, struct uuid *uuid, + prs_struct *ps, int depth) { if (uuid == NULL) return False; - prs_debug(ps, depth, desc, "smb_io_rpc_uuid"); + prs_debug(ps, depth, desc, "smb_io_uuid"); depth++; if(!prs_uint32 ("data ", ps, depth, &uuid->time_low)) @@ -281,7 +297,9 @@ BOOL smb_io_rpc_uuid(const char *desc, RPC_UUID *uuid, prs_struct *ps, int depth if(!prs_uint16 ("data ", ps, depth, &uuid->time_hi_and_version)) return False; - if(!prs_uint8s (False, "data ", ps, depth, uuid->remaining, sizeof(uuid->remaining))) + if(!prs_uint8s (False, "data ", ps, depth, uuid->clock_seq, sizeof(uuid->clock_seq))) + return False; + if(!prs_uint8s (False, "data ", ps, depth, uuid->node, sizeof(uuid->node))) return False; return True; @@ -302,7 +320,7 @@ static BOOL smb_io_rpc_iface(const char *desc, RPC_IFACE *ifc, prs_struct *ps, i if (!prs_align(ps)) return False; - if (!smb_io_rpc_uuid( "uuid", &ifc->uuid, ps, depth)) + if (!smb_io_uuid( "uuid", &ifc->uuid, ps, depth)) return False; if(!prs_uint32 ("version", ps, depth, &ifc->version)) diff --git a/source3/rpc_server/srv_epmapper_nt.c b/source3/rpc_server/srv_epmapper_nt.c index 1b72a5ed41..e82484af4a 100644 --- a/source3/rpc_server/srv_epmapper_nt.c +++ b/source3/rpc_server/srv_epmapper_nt.c @@ -43,7 +43,7 @@ void _epm_map(pipes_struct *ps, const EPM_Q_MAP *q_u, EPM_R_MAP *r_u) switch (q_u->tower->floors[i].lhs.protocol) { case EPM_FLOOR_UUID: init_epm_floor_uuid(&floors[i], - &q_u->tower->floors[i]. + q_u->tower->floors[i]. lhs.uuid.uuid, q_u->tower->floors[i]. lhs.uuid.version); diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 444c35987a..7bbe726f5a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -731,9 +731,9 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, { if ( strequal(pipe_names[i].client_pipe, pname) && (abstract->version == pipe_names[i].abstr_syntax.version) - && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(RPC_UUID)) == 0) + && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct uuid)) == 0) && (transfer->version == pipe_names[i].trans_syntax.version) - && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) == 0) ) + && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct uuid)) == 0) ) { struct api_struct *fns = NULL; int n_fns = 0; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 15578f6148..ad8f5af432 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4358,10 +4358,11 @@ static BOOL construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *p static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum) { char *guid_str = NULL; - GUID guid; + UUID_FLAT guid; if (is_printer_published(print_hnd, snum, &guid)) { - asprintf(&guid_str, "{%s}", smb_uuid_string_static(guid)); + asprintf(&guid_str, "{%s}", + smb_uuid_string_static(smb_uuid_unpack_static(guid))); strupper_m(guid_str); init_unistr(&printer->guid, guid_str); printer->action = SPOOL_DS_PUBLISH; diff --git a/source3/rpcclient/cmd_epmapper.c b/source3/rpcclient/cmd_epmapper.c index e2eecb6f04..4998286194 100644 --- a/source3/rpcclient/cmd_epmapper.c +++ b/source3/rpcclient/cmd_epmapper.c @@ -34,19 +34,21 @@ static NTSTATUS cmd_epm_map(struct cli_state *cli, uint32 numtowers; /* need to allow all this stuff to be passed in, but for now, it demonstrates the call */ - RPC_UUID if_uuid = {0xe3514235, 0x4b06, 0x11d1, \ - { 0xab, 0x04, 0x00, 0xc0, \ - 0x4f, 0xc2, 0xdc, 0xd2 }}, - syn_uuid = {0x8a885d04, 0x1ceb, 0x11c9, \ - { 0x9f, 0xe8, 0x08, 0x00, \ - 0x2b, 0x10, 0x48, 0x60 }}; + struct uuid if_uuid = {0xe3514235, 0x4b06, 0x11d1, \ + { 0xab, 0x04 }, \ + { 0x00, 0xc0, \ + 0x4f, 0xc2, 0xdc, 0xd2 } }, + syn_uuid = {0x8a885d04, 0x1ceb, 0x11c9, \ + { 0x9f, 0xe8 }, \ + { 0x08, 0x00, \ + 0x2b, 0x10, 0x48, 0x60 } }; NTSTATUS result; ZERO_STRUCT(handle); numtowers = 1; - init_epm_floor_uuid(&floors[0], &if_uuid, 4); - init_epm_floor_uuid(&floors[1], &syn_uuid, 2); + init_epm_floor_uuid(&floors[0], if_uuid, 4); + init_epm_floor_uuid(&floors[1], syn_uuid, 2); init_epm_floor_rpc(&floors[2]); /* sample for netbios named pipe query diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index db74370bc0..d4509eae44 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -69,7 +69,7 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID dom_sid; - GUID dom_guid; + UUID_FLAT dom_guid; fstring sid_str, domain_name="", dns_name="", forest_name=""; uint32 info_class = 3; @@ -123,8 +123,9 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, printf("forest name is %s\n", forest_name); if (info_class == 12) { - printf("domain GUID is "); - print_guid(&dom_guid); + printf("domain GUID is %s\n", + smb_uuid_string_static( + smb_uuid_unpack_static(dom_guid))); } done: return result; diff --git a/source3/utils/net_ads_cldap.c b/source3/utils/net_ads_cldap.c index 44de9cb891..1903172cf7 100644 --- a/source3/utils/net_ads_cldap.c +++ b/source3/utils/net_ads_cldap.c @@ -29,7 +29,7 @@ struct cldap_netlogon_reply { uint32 type; uint32 flags; - GUID guid; + UUID_FLAT guid; char forest[MAX_DNS_LABEL]; char domain[MAX_DNS_LABEL]; @@ -241,8 +241,8 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) reply->type = IVAL(p, 0); p += 4; reply->flags = IVAL(p, 0); p += 4; - memcpy(&reply->guid.info, p, GUID_SIZE); - p += GUID_SIZE; + memcpy(&reply->guid.info, p, UUID_FLAT_SIZE); + p += UUID_FLAT_SIZE; p += pull_netlogon_string(reply->forest, p, (const char *)os3.data); p += pull_netlogon_string(reply->domain, p, (const char *)os3.data); @@ -316,8 +316,8 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) d_printf("0x%x\n", reply.type); break; } - d_printf("GUID: "); - print_guid(&reply.guid); + d_printf("GUID: %s\n", + smb_uuid_string_static(smb_uuid_unpack_static(reply.guid))); d_printf("Flags:\n" "\tIs a PDC: %s\n" "\tIs a GC of the forest: %s\n" -- cgit From 1587245a053fc82b74dea06689e9d5fe0ce91eea Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 30 Oct 2003 17:07:32 +0000 Subject: Another round of GUID->struct uuid. Takes care of the lsass pipe (This used to be commit 3dca3efa4b427fa3094a8cd392fe5744b5f6f6a8) --- source3/include/rpc_lsa.h | 2 +- source3/rpc_client/cli_lsarpc.c | 5 +++-- source3/rpc_parse/parse_lsa.c | 2 +- source3/rpc_server/srv_lsa_nt.c | 6 +++--- source3/rpcclient/cmd_lsarpc.c | 5 ++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index 2064a38056..43ffa37d59 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -275,7 +275,7 @@ typedef struct lsa_dns_dom_info UNIHDR hdr_dns_dom_name; UNIHDR hdr_forest_name; - GUID dom_guid; /* domain GUID */ + struct uuid dom_guid; /* domain GUID */ UNISTR2 uni_nb_dom_name; UNISTR2 uni_dns_dom_name; diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index ab4fbad613..163e847922 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -537,7 +537,8 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_lsa_query_info_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint16 info_class, fstring domain_name, fstring dns_name, - fstring forest_name, GUID *domain_guid, + fstring forest_name, + struct uuid *domain_guid, DOM_SID *domain_sid) { prs_struct qbuf, rbuf; @@ -599,7 +600,7 @@ NTSTATUS cli_lsa_query_info_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, sizeof(fstring) - 1); } - memcpy(domain_guid, &r.info.dns_dom_info.dom_guid, sizeof(GUID)); + memcpy(domain_guid, &r.info.dns_dom_info.dom_guid,sizeof(struct uuid)); if (r.info.dns_dom_info.ptr_dom_sid != 0) { *domain_sid = r.info.dns_dom_info.dom_sid.sid; diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index f960345fe7..992433f4bb 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -2142,7 +2142,7 @@ BOOL lsa_io_dns_dom_info(const char *desc, LSA_DNS_DOM_INFO *info, if(!prs_align(ps)) return False; - if (!prs_uint8s(False, "dom_guid", ps, depth, info->dom_guid.info, GUID_SIZE)) + if ( !smb_io_uuid("dom_guid", &info->dom_guid, ps, depth) ) return False; if(!prs_align(ps)) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 0a8ad404cb..db5c8c83b0 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -348,7 +348,7 @@ static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *s static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name, const char *dns_name, const char *forest_name, - GUID *dom_guid, DOM_SID *dom_sid) + struct uuid *dom_guid, DOM_SID *dom_sid) { if (nb_name && *nb_name) { init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE); @@ -373,7 +373,7 @@ static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name, /* how do we init the guid ? probably should write an init fn */ if (dom_guid) { - memcpy(&r_l->dom_guid, dom_guid, sizeof(GUID)); + memcpy(&r_l->dom_guid, dom_guid, sizeof(struct uuid)); } if (dom_sid) { @@ -1219,7 +1219,7 @@ NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_I char *dns_name = NULL; char *forest_name = NULL; DOM_SID *sid = NULL; - GUID guid; + struct uuid guid; fstring dnsdomname; ZERO_STRUCT(guid); diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index d4509eae44..217e6b1d68 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -69,7 +69,7 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID dom_sid; - UUID_FLAT dom_guid; + struct uuid dom_guid; fstring sid_str, domain_name="", dns_name="", forest_name=""; uint32 info_class = 3; @@ -124,8 +124,7 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, if (info_class == 12) { printf("domain GUID is %s\n", - smb_uuid_string_static( - smb_uuid_unpack_static(dom_guid))); + smb_uuid_string_static(dom_guid)); } done: return result; -- cgit From bb971b44b84a72d628205fba0c27207f5fd00bf2 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 30 Oct 2003 17:17:51 +0000 Subject: More GUID->struct uuid changes. Printer publishing now uses struct uuid. Also changes ads_pull_guid to unpack it from the wire format. (This used to be commit 671b434cc4b422144ab8f5858ae9c2179de701e1) --- source3/libads/ldap.c | 6 ++++-- source3/printing/nt_printing.c | 17 ++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ed26bf07f2..2ee8e6fe93 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1623,16 +1623,18 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, * @return boolean indicating success **/ BOOL ads_pull_guid(ADS_STRUCT *ads, - void *msg, GUID *guid) + void *msg, struct uuid *guid) { char **values; + UUID_FLAT flat_guid; values = ldap_get_values(ads->ld, msg, "objectGUID"); if (!values) return False; if (values[0]) { - memcpy(guid, values[0], sizeof(GUID)); + memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT)); + smb_uuid_unpack(flat_guid, guid); ldap_value_free(values); return True; } diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 908bd9c887..0b4fa93b5a 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2576,7 +2576,8 @@ static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2) return True; } -static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, GUID guid) +static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, + struct uuid guid) { int i; REGVAL_CTR *ctr=NULL; @@ -2588,7 +2589,7 @@ static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, GUID guid) regval_ctr_delvalue(ctr, "objectGUID"); regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY, - (char *) &guid, sizeof(GUID)); + (char *) &guid, sizeof(struct uuid)); } static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer) @@ -2601,7 +2602,7 @@ static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer) void *res = NULL; ADS_STRUCT *ads; const char *attrs[] = {"objectGUID", NULL}; - GUID guid; + struct uuid guid; WERROR win_rc = WERR_OK; ZERO_STRUCT(guid); @@ -2785,7 +2786,8 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) return win_rc; } -BOOL is_printer_published(Printer_entry *print_hnd, int snum, GUID *guid) +BOOL is_printer_published(Printer_entry *print_hnd, int snum, + struct uuid *guid) { NT_PRINTER_INFO_LEVEL *printer = NULL; REGVAL_CTR *ctr; @@ -2813,8 +2815,8 @@ BOOL is_printer_published(Printer_entry *print_hnd, int snum, GUID *guid) return False; } - if (regval_size(guid_val) == sizeof(GUID)) - memcpy(guid, regval_data_p(guid_val), sizeof(GUID)); + if (regval_size(guid_val) == sizeof(struct uuid)) + memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid)); return True; } @@ -2824,7 +2826,8 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) { return WERR_OK; } -BOOL is_printer_published(Printer_entry *print_hnd, int snum, GUID *guid) +BOOL is_printer_published(Printer_entry *print_hnd, int snum, + struct uuid *guid) { return False; } -- cgit From 4f22327e21cc442f954a87835c377e11568d4cf4 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 30 Oct 2003 17:37:21 +0000 Subject: Ok, nearing the end of the GUID->struct uuid changes. Takes care of secdescs. Had to move the uuid marshall/unmarshalling code to parse_misc, because it's needed outside of parse_rpc.c (for no-auth calls) (This used to be commit 5d2bb079b65ccfec14604d8dcf0ce789d1795b46) --- source3/include/rpc_secdes.h | 4 ++-- source3/lib/secace.c | 4 ++-- source3/rpc_parse/parse_misc.c | 28 ++++++++++++++++++++++++++++ source3/rpc_parse/parse_rpc.c | 28 ---------------------------- source3/rpc_parse/parse_sec.c | 4 ++-- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h index 5e718f8167..4bb39dc935 100644 --- a/source3/include/rpc_secdes.h +++ b/source3/include/rpc_secdes.h @@ -138,8 +138,8 @@ typedef struct security_ace_info /* this stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */ uint32 obj_flags; /* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */ - GUID obj_guid; /* object GUID */ - GUID inh_guid; /* inherited object GUID */ + struct uuid obj_guid; /* object GUID */ + struct uuid inh_guid; /* inherited object GUID */ /* eof object stuff */ DOM_SID trustee; diff --git a/source3/lib/secace.c b/source3/lib/secace.c index 6769f1288a..8c54c97043 100644 --- a/source3/lib/secace.c +++ b/source3/lib/secace.c @@ -48,8 +48,8 @@ void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src) ace_dest->size = ace_src->size; ace_dest->info.mask = ace_src->info.mask; ace_dest->obj_flags = ace_src->obj_flags; - memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, GUID_SIZE); - memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, GUID_SIZE); + memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, sizeof(struct uuid)); + memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, sizeof(struct uuid)); sid_copy(&ace_dest->trustee, &ace_src->trustee); } diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index e182535532..a075dbd833 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -322,6 +322,34 @@ BOOL smb_io_dom_sid2(const char *desc, DOM_SID2 *sid, prs_struct *ps, int depth) return True; } +/******************************************************************* + Reads or writes a struct uuid +********************************************************************/ + +BOOL smb_io_uuid(const char *desc, struct uuid *uuid, + prs_struct *ps, int depth) +{ + if (uuid == NULL) + return False; + + prs_debug(ps, depth, desc, "smb_io_uuid"); + depth++; + + if(!prs_uint32 ("data ", ps, depth, &uuid->time_low)) + return False; + if(!prs_uint16 ("data ", ps, depth, &uuid->time_mid)) + return False; + if(!prs_uint16 ("data ", ps, depth, &uuid->time_hi_and_version)) + return False; + + if(!prs_uint8s (False, "data ", ps, depth, uuid->clock_seq, sizeof(uuid->clock_seq))) + return False; + if(!prs_uint8s (False, "data ", ps, depth, uuid->node, sizeof(uuid->node))) + return False; + + return True; +} + /******************************************************************* creates a STRHDR structure. ********************************************************************/ diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index 1718841cf7..696f258e5d 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -277,34 +277,6 @@ BOOL smb_io_rpc_hdr(const char *desc, RPC_HDR *rpc, prs_struct *ps, int depth) return True; } -/******************************************************************* - Reads or writes a struct uuid -********************************************************************/ - -BOOL smb_io_uuid(const char *desc, struct uuid *uuid, - prs_struct *ps, int depth) -{ - if (uuid == NULL) - return False; - - prs_debug(ps, depth, desc, "smb_io_uuid"); - depth++; - - if(!prs_uint32 ("data ", ps, depth, &uuid->time_low)) - return False; - if(!prs_uint16 ("data ", ps, depth, &uuid->time_mid)) - return False; - if(!prs_uint16 ("data ", ps, depth, &uuid->time_hi_and_version)) - return False; - - if(!prs_uint8s (False, "data ", ps, depth, uuid->clock_seq, sizeof(uuid->clock_seq))) - return False; - if(!prs_uint8s (False, "data ", ps, depth, uuid->node, sizeof(uuid->node))) - return False; - - return True; -} - /******************************************************************* Reads or writes an RPC_IFACE structure. ********************************************************************/ diff --git a/source3/rpc_parse/parse_sec.c b/source3/rpc_parse/parse_sec.c index bf43ef288a..a78627650a 100644 --- a/source3/rpc_parse/parse_sec.c +++ b/source3/rpc_parse/parse_sec.c @@ -83,11 +83,11 @@ BOOL sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth) return False; if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT) - if (!prs_uint8s(False, "obj_guid", ps, depth, psa->obj_guid.info, GUID_SIZE)) + if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth)) return False; if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT) - if (!prs_uint8s(False, "inh_guid", ps, depth, psa->inh_guid.info, GUID_SIZE)) + if (!smb_io_uuid("inh_guid", &psa->inh_guid, ps,depth)) return False; if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth)) -- cgit From bff3e7feee2c9ef91a487df410327666c38602c1 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 30 Oct 2003 17:50:56 +0000 Subject: Nearing the end of the GUID -> struct uuid changes. (This used to be commit 0e8fcfac702515f8870c979262bf881d1155efdc) --- source3/lib/util_uuid.c | 12 ++++++------ source3/nmbd/nmbd_processlogon.c | 9 ++++++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/source3/lib/util_uuid.c b/source3/lib/util_uuid.c index 8217006e58..fe8595c8cb 100644 --- a/source3/lib/util_uuid.c +++ b/source3/lib/util_uuid.c @@ -27,13 +27,13 @@ #define TIME_OFFSET_HIGH 0x01B21DD2 #define TIME_OFFSET_LOW 0x13814000 -void smb_uuid_pack(const struct uuid *uu, UUID_FLAT *ptr) +void smb_uuid_pack(const struct uuid uu, UUID_FLAT *ptr) { - SIVAL(ptr, 0, uu->time_low); - SSVAL(ptr, 4, uu->time_mid); - SSVAL(ptr, 6, uu->time_hi_and_version); - memcpy(ptr+8, uu->clock_seq, 2); - memcpy(ptr+10, uu->node, 6); + SIVAL(ptr, 0, uu.time_low); + SSVAL(ptr, 4, uu.time_mid); + SSVAL(ptr, 6, uu.time_hi_and_version); + memcpy(ptr+8, uu.clock_seq, 2); + memcpy(ptr+10, uu.node, 6); } void smb_uuid_unpack(const UUID_FLAT in, struct uuid *uu) diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index 816b351464..fc66e0d6b4 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -313,7 +313,8 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", } #ifdef HAVE_ADS else { - GUID domain_guid; + struct uuid domain_guid; + UUID_FLAT flat_guid; pstring domain; pstring hostname; char *component, *dc, *q1; @@ -340,8 +341,10 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain)); return; } - memcpy(q, &domain_guid, sizeof(domain_guid)); - q += sizeof(domain_guid); + + smb_uuid_pack(domain_guid, &flat_guid); + memcpy(q, &flat_guid.info, UUID_FLAT_SIZE); + q += UUID_FLAT_SIZE; /* Forest */ str_offset = q - q_orig; -- cgit From 2e65aa1b284f34d62f8b54ddb19d2d87d4379433 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 30 Oct 2003 18:13:25 +0000 Subject: Last of the GUID->struct uuid changes. GUID has been removed. If you are dealing with a flattened version of a [gu]uid, use UUID_FLAT. smb_pack_uuid and smb_unpack_uuid will switch between the two. I'm not sure exactly what the genparse stuff is doing here, so I just switched it to a UUID_FLAT (no functional change), but I suspect this may not be the right way to go. (This used to be commit 001e9d0e814109a26d598001b3c23dfdb04510ff) --- source3/include/rpc_secdes.h | 7 ------- source3/lib/genparser_samba.c | 14 +++++++------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h index 4bb39dc935..56145ac024 100644 --- a/source3/include/rpc_secdes.h +++ b/source3/include/rpc_secdes.h @@ -113,13 +113,6 @@ PROTECTED_SACL_SECURITY_INFORMATION|\ PROTECTED_DACL_SECURITY_INFORMATION) -/* Globally Unique ID */ -#define GUID_SIZE 16 -typedef struct guid_info -{ - uint8 info[GUID_SIZE]; -} GUID; - /* SEC_ACCESS */ typedef struct security_info_info { diff --git a/source3/lib/genparser_samba.c b/source3/lib/genparser_samba.c index 7eabf5a56e..8f469a46d6 100644 --- a/source3/lib/genparser_samba.c +++ b/source3/lib/genparser_samba.c @@ -63,7 +63,7 @@ int gen_parse_SEC_ACCESS(TALLOC_CTX *mem_ctx, char *ptr, const char *str) int gen_parse_GUID(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - int info[GUID_SIZE]; + int info[UUID_FLAT_SIZE]; int i; char *sc; char *p; @@ -74,7 +74,7 @@ int gen_parse_GUID(TALLOC_CTX *mem_ctx, char *ptr, const char *str) sc = m; memset(info, 0, sizeof(info)); - for (i = 0; i < GUID_SIZE; i++) { + for (i = 0; i < UUID_FLAT_SIZE; i++) { p = strchr(sc, ','); if (p != NULL) p = '\0'; info[i] = atoi(sc); @@ -82,8 +82,8 @@ int gen_parse_GUID(TALLOC_CTX *mem_ctx, char *ptr, const char *str) } free(m); - for (i = 0; i < GUID_SIZE; i++) { - ((GUID *)ptr)->info[i] = info[i]; + for (i = 0; i < UUID_FLAT_SIZE; i++) { + ((UUID_FLAT *)ptr)->info[i] = info[i]; } return 0; @@ -172,10 +172,10 @@ int gen_dump_GUID(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, { int i, r; - for (i = 0; i < (GUID_SIZE - 1); i++) { - if (!(r = addshort(mem_ctx, p, "%d,", ((GUID *)ptr)->info[i]))) return r; + for (i = 0; i < (UUID_FLAT_SIZE - 1); i++) { + if (!(r = addshort(mem_ctx, p, "%d,", ((UUID_FLAT *)ptr)->info[i]))) return r; } - return addshort(mem_ctx, p, "%d", ((GUID *)ptr)->info[i]); + return addshort(mem_ctx, p, "%d", ((UUID_FLAT *)ptr)->info[i]); } int gen_dump_SEC_ACE(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) -- cgit From 29f33e828720a01224f9fe40ac156a1c51be41ba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 30 Oct 2003 20:09:44 +0000 Subject: If nothing to do, return success. Fix from Aur?lien Degr?mont Jeremy. (This used to be commit a92555e6060294afcfecc075bfac5c836f150b01) --- source3/passdb/pdb_ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index fdc79ae2ab..e0148494d3 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1987,7 +1987,7 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods, if (mods == NULL) { DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: nothing to do\n")); - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_OK; } dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry); -- cgit From 8270b9bd298719e81646abf19caf42e452752090 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 30 Oct 2003 23:43:18 +0000 Subject: Add string to uuid fn. Thanks aliguori. (This used to be commit 5f9fe8304f037f91fa765e64580a7119aeb201dd) --- source3/lib/util_uuid.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/source3/lib/util_uuid.c b/source3/lib/util_uuid.c index fe8595c8cb..4c35236c90 100644 --- a/source3/lib/util_uuid.c +++ b/source3/lib/util_uuid.c @@ -2,7 +2,7 @@ * Unix SMB/CIFS implementation. * UUID server routines * Copyright (C) Theodore Ts'o 1996, 1997, - * Copyright (C) Jim McDonough 2002. + * Copyright (C) Jim McDonough 2002, 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 @@ -89,3 +89,86 @@ const char *smb_uuid_string_static(const struct uuid uu) uu.node[3], uu.node[4], uu.node[5]); return out; } + +BOOL smb_string_to_uuid(const char *in, struct uuid* uu) +{ + BOOL ret = False; + const char *ptr = in; + char *end = (char *)in; + int i; + + if (!in || !uu) goto out; + + uu->time_low = strtoul(ptr, &end, 16); + if ((end - ptr) != 8 || *end != '-') goto out; + ptr = (end + 1); + + uu->time_mid = strtoul(ptr, &end, 16); + if ((end - ptr) != 4 || *end != '-') goto out; + ptr = (end + 1); + + uu->time_hi_and_version = strtoul(ptr, &end, 16); + if ((end - ptr) != 4 || *end != '-') goto out; + ptr = (end + 1); + + for (i = 0; i < 2; i++) { + int adj = 0; + if (*ptr >= '0' && *ptr <= '9') { + adj = '0'; + } else if (*ptr >= 'a' && *ptr <= 'f') { + adj = 'a'; + } else if (*ptr >= 'A' && *ptr <= 'F') { + adj = 'A'; + } else { + goto out; + } + uu->clock_seq[i] = (*ptr - adj) << 4; + ptr++; + + if (*ptr >= '0' && *ptr <= '9') { + adj = '0'; + } else if (*ptr >= 'a' && *ptr <= 'f') { + adj = 'a'; + } else if (*ptr >= 'A' && *ptr <= 'F') { + adj = 'A'; + } else { + goto out; + } + uu->clock_seq[i] |= (*ptr - adj); + ptr++; + } + + if (*ptr != '-') goto out; + ptr++; + + for (i = 0; i < 6; i++) { + int adj = 0; + if (*ptr >= '0' && *ptr <= '9') { + adj = '0'; + } else if (*ptr >= 'a' && *ptr <= 'f') { + adj = 'a'; + } else if (*ptr >= 'A' && *ptr <= 'F') { + adj = 'A'; + } else { + goto out; + } + uu->node[i] = (*ptr - adj) << 4; + ptr++; + + if (*ptr >= '0' && *ptr <= '9') { + adj = '0'; + } else if (*ptr >= 'a' && *ptr <= 'f') { + adj = 'a'; + } else if (*ptr >= 'A' && *ptr <= 'F') { + adj = 'A'; + } else { + goto out; + } + uu->node[i] |= (*ptr - adj); + ptr++; + } + + ret = True; +out: + return ret; +} -- cgit From b7047b353970b2cd982ec5f97798f4ad0df844c7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 01:17:37 +0000 Subject: Merge of some fixes from 3.0: - Revision 1.468.2.187 CP* modules are not related to development - Revision 1.468.2.191 Compile fix for tdbbackup when Samba needs to override non-C99 compliant implementations of snprintf Sync up formatting for PAM_WINBIND_PICOBJ variable. (This used to be commit b4f3c8d2f62e6d75a5c01529190e71289dea8df5) --- source3/Makefile.in | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index b0d9be55ec..d409723254 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -298,8 +298,8 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ XML_OBJ = passdb/pdb_xml.o MYSQL_OBJ = passdb/pdb_mysql.o DEVEL_HELP_WEIRD_OBJ = modules/weird.o -DEVEL_HELP_CP850_OBJ = modules/CP850.o -DEVEL_HELP_CP437_OBJ = modules/CP437.o +CP850_OBJ = modules/CP850.o +CP437_OBJ = modules/CP437.o GROUPDB_OBJ = groupdb/mapping.o @@ -458,7 +458,9 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ $(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \ $(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o -PAM_WINBIND_PICOBJ = nsswitch/pam_winbind.@PICSUFFIX@ nsswitch/wb_common.@PICSUFFIX@ lib/replace1.@PICSUFFIX@ lib/snprintf.@PICSUFFIX@ +PAM_WINBIND_PICOBJ = nsswitch/pam_winbind.@PICSUFFIX@ \ + nsswitch/wb_common.@PICSUFFIX@ lib/replace1.@PICSUFFIX@ \ + lib/snprintf.@PICSUFFIX@ SMBW_OBJ1 = smbwrapper/smbw.o \ smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \ @@ -641,7 +643,7 @@ WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.@PICSUFFIX@) lib/snprintf.@PICSUFFIX POPT_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \ popt/popthelp.o popt/poptparse.o -TDBBACKUP_OBJ = tdb/tdbbackup.o tdb/tdbback.o $(TDBBASE_OBJ) +TDBBACKUP_OBJ = tdb/tdbbackup.o tdb/tdbback.o lib/snprintf.o $(TDBBASE_OBJ) NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \ @@ -1092,14 +1094,14 @@ bin/weird.@SHLIBEXT@: $(DEVEL_HELP_WEIRD_OBJ:.o=.@PICSUFFIX@) @$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_WEIRD_OBJ:.o=.@PICSUFFIX@) \ @SONAMEFLAG@`basename $@` -bin/CP850.@SHLIBEXT@: $(DEVEL_HELP_CP850_OBJ:.o=.@PICSUFFIX@) +bin/CP850.@SHLIBEXT@: $(CP850_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" - @$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_CP850_OBJ:.o=.@PICSUFFIX@) \ + @$(SHLD) $(LDSHFLAGS) -o $@ $(CP850_OBJ:.o=.@PICSUFFIX@) \ @SONAMEFLAG@`basename $@` -bin/CP437.@SHLIBEXT@: $(DEVEL_HELP_CP437_OBJ:.o=.@PICSUFFIX@) +bin/CP437.@SHLIBEXT@: $(CP437_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" - @$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_CP437_OBJ:.o=.@PICSUFFIX@) \ + @$(SHLD) $(LDSHFLAGS) -o $@ $(CP437_OBJ:.o=.@PICSUFFIX@) \ @SONAMEFLAG@`basename $@` bin/xml.@SHLIBEXT@: $(XML_OBJ:.o=.@PICSUFFIX@) -- cgit From 64b97d0aa9986641bbb3b71f7fbdd27b2e5b6278 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 01:18:41 +0000 Subject: Merge from 3.0: Sync up comments. (This used to be commit c00bd547c875a1eba3b8c427f4fed0b61ae987c5) --- source3/aclocal.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/aclocal.m4 b/source3/aclocal.m4 index c7831c58ca..5169eee41b 100644 --- a/source3/aclocal.m4 +++ b/source3/aclocal.m4 @@ -125,11 +125,11 @@ AC_DEFUN(AC_LIBTESTFUNC, # may have different results. # # Note that using directly AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1_$3]) -# is asking for troubles, since AC_CHECK_LIB($lib, fun) would give +# is asking for trouble, since AC_CHECK_LIB($lib, fun) would give # ac_cv_lib_$lib_fun, which is definitely not what was meant. Hence # the AS_LITERAL_IF indirection. # -# FIXME: This macro is extremely suspicious. It DEFINEs unconditionnally, +# FIXME: This macro is extremely suspicious. It DEFINEs unconditionally, # whatever the FUNCTION, in addition to not being a *S macro. Note # that the cache does depend upon the function we are looking for. # -- cgit From 483dc4feb5ad997ac88757db04beafbcf432e826 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 01:31:31 +0000 Subject: Sync up some indentation. (This used to be commit 160903f99782673a3ff147450d33f4a4ff88a666) --- source3/configure.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index f0a2c3c3f3..bbade6027f 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1680,9 +1680,9 @@ dnl ]) LIBS="$ic_save_LIBS" if test x"$samba_cv_HAVE_NATIVE_ICONV" = x"yes"; then - CPPFLAGS=$save_CPPFLAGS - CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") - export CPPFLAGS + CPPFLAGS=$save_CPPFLAGS + CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") + export CPPFLAGS AC_DEFINE(HAVE_NATIVE_ICONV,1,[Whether to use native iconv]) AC_DEFINE_UNQUOTED(DEFAULT_DOS_CHARSET,$default_dos_charset,[Default dos charset name]) AC_DEFINE_UNQUOTED(DEFAULT_DISPLAY_CHARSET,$default_display_charset,[Default display charset name]) -- cgit From c6ac467d39e63829c17ca0e54677419e466a5304 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 01:35:02 +0000 Subject: Sync up with 3.0 (This used to be commit 3cd8acb6c362bca82d7268aa283d3f6360b24604) --- source3/include/.cvsignore | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/include/.cvsignore b/source3/include/.cvsignore index 3827fdf70d..7dff121f14 100644 --- a/source3/include/.cvsignore +++ b/source3/include/.cvsignore @@ -1,7 +1,7 @@ build_env.h config.h -config.h.in -proto.h stamp-h -version.h +proto.h wrepld_proto.h +config.h.in +version.h -- cgit From a51e72a19b3fba09086bc318f145169d6d902a04 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 01:42:21 +0000 Subject: Merge from 3.0: Revision 1.2.2.5: Remove some unused variables uncovered by the build farm. (This used to be commit c0585399ac3b6adb22b514478ba44e3c8a96b050) --- source3/libsmb/libsmb_compat.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 4c96c41c56..cc23835ae3 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -115,9 +115,6 @@ static int del_fd(int fd) int smbc_init(smbc_get_auth_data_fn fn, int debug) { - int i; - struct smbc_compat_fdlist * f; - if (!smbc_compat_initialized) { statcont = smbc_new_context(); if (!statcont) -- cgit From 956a16d6efe00de48c41d84621b925f246825cdb Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 02:53:07 +0000 Subject: Fix some unused variable warnings. (This used to be commit 512a81c9fd4490cb6f9b1cc88cdb9238d21decb1) --- source3/sam/gums.c | 2 ++ source3/sam/gums_tdbsam2.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/source3/sam/gums.c b/source3/sam/gums.c index ab374b9342..91009f8b5d 100644 --- a/source3/sam/gums.c +++ b/source3/sam/gums.c @@ -58,6 +58,7 @@ static GUMS_FUNCTIONS *gums_backend = NULL; +#if 0 static PRIVS gums_privs[] = { {PRIV_NONE, "no_privs", "No privilege"}, /* this one MUST be first */ {PRIV_CREATE_TOKEN, "SeCreateToken", "Create Token"}, @@ -88,6 +89,7 @@ static PRIVS gums_privs[] = { {PRIV_ENABLE_DELEGATION, "SeEnableDelegation", "Enable Delegation"}, {PRIV_ALL, "SaAllPrivs", "All Privileges"} }; +#endif static struct gums_init_function_entry *backends = NULL; diff --git a/source3/sam/gums_tdbsam2.c b/source3/sam/gums_tdbsam2.c index 82e3923f7c..217cf6f34e 100644 --- a/source3/sam/gums_tdbsam2.c +++ b/source3/sam/gums_tdbsam2.c @@ -22,7 +22,9 @@ #include "tdbsam2.h" #include "tdbsam2_parse_info.h" +#if 0 static int gums_tdbsam2_debug_class = DBGC_ALL; +#endif /* #undef DBGC_CLASS #define DBGC_CLASS gums_tdbsam2_debug_class @@ -1182,6 +1184,7 @@ static NTSTATUS tdbsam2_set_object(const GUMS_OBJECT *go) return ret; } +#if 0 /* set object values function */ static NTSTATUS (*set_object_values) (DOM_SID *sid, uint32 count, GUMS_DATA_SET *data_set); @@ -1203,6 +1206,7 @@ static NTSTATUS (*enumerate_privilege_members) (DOM_SID **members, const LUID_AT static NTSTATUS (*get_sid_privileges) (DOM_SID **privs, const DOM_SID *sid); /* warning!: set_privilege will overwrite a prior existing privilege if such exist */ static NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv); +#endif static void free_tdbsam2_private_data(void **vp) { -- cgit From adcd3e42b4dc200116e260e5db5fe32b55fe5eb5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 02:56:11 +0000 Subject: Merge from 3.0: Revision 1.45.2.23: Changed output so all debug output goes to stderr, and all file processing goes to stdout. Note: This change permits use of testparm processing of smb.conf to be redirected into a file that can be used as an smb.conf file. ie: All information that should not be in smb.conf will be on stderr, all pertinent smb.conf info will go to stdout. Example of use: A fully documented smb.conf.master file can be maintained. To create smb.conf do: testparm -s > smb.conf (This used to be commit f323b932f932a576d42a018a3e16b45758121891) --- source3/utils/testparm.c | 80 ++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c index 085156305b..a74c2eaa97 100644 --- a/source3/utils/testparm.c +++ b/source3/utils/testparm.c @@ -47,28 +47,28 @@ static int do_global_checks(void) SMB_STRUCT_STAT st; if (lp_security() >= SEC_DOMAIN && !lp_encrypted_passwords()) { - printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must always be set to 'true'.\n"); + fprintf(stderr, "ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must always be set to 'true'.\n"); ret = 1; } if (lp_wins_support() && lp_wins_server_list()) { - printf("ERROR: both 'wins support = true' and 'wins server = ' \ + fprintf(stderr, "ERROR: both 'wins support = true' and 'wins server = ' \ cannot be set in the smb.conf file. nmbd will abort with this setting.\n"); ret = 1; } if (!directory_exist(lp_lockdir(), &st)) { - printf("ERROR: lock directory %s does not exist\n", + fprintf(stderr, "ERROR: lock directory %s does not exist\n", lp_lockdir()); ret = 1; } else if ((st.st_mode & 0777) != 0755) { - printf("WARNING: lock directory %s should have permissions 0755 for browsing to work\n", + fprintf(stderr, "WARNING: lock directory %s should have permissions 0755 for browsing to work\n", lp_lockdir()); ret = 1; } if (!directory_exist(lp_piddir(), &st)) { - printf("ERROR: pid directory %s does not exist\n", + fprintf(stderr, "ERROR: pid directory %s does not exist\n", lp_piddir()); ret = 1; } @@ -84,7 +84,7 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n"); else if(lp_security() == SEC_DOMAIN) pstrcpy(sec_setting, "domain"); - printf("ERROR: The setting 'security=%s' requires the 'password server' parameter be set \ + fprintf(stderr, "ERROR: The setting 'security=%s' requires the 'password server' parameter be set \ to a valid password server.\n", sec_setting ); ret = 1; } @@ -95,7 +95,7 @@ to a valid password server.\n", sec_setting ); */ if(*lp_hosts_equiv() && !lp_hostname_lookups()) { - printf("ERROR: The setting 'hosts equiv = %s' requires that 'hostname lookups = yes'.\n", lp_hosts_equiv()); + fprintf(stderr, "ERROR: The setting 'hosts equiv = %s' requires that 'hostname lookups = yes'.\n", lp_hosts_equiv()); ret = 1; } @@ -114,7 +114,7 @@ to a valid password server.\n", sec_setting ); #endif if(lp_passwd_program() == NULL) { - printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \ + fprintf( stderr, "ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \ parameter.\n" ); ret = 1; } else { @@ -128,7 +128,7 @@ parameter.\n" ); next_token(&p, truncated_prog, NULL, sizeof(pstring)); if(access(truncated_prog, F_OK) == -1) { - printf("ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \ + fprintf(stderr, "ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \ cannot be executed (error was %s).\n", truncated_prog, strerror(errno) ); ret = 1; } @@ -139,7 +139,7 @@ cannot be executed (error was %s).\n", truncated_prog, strerror(errno) ); #endif if(lp_passwd_chat() == NULL) { - printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \ + fprintf(stderr, "ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \ parameter.\n"); ret = 1; } @@ -151,7 +151,7 @@ parameter.\n"); if(lp_encrypted_passwords()) { if(strstr( lp_passwd_chat(), "%o")!=NULL) { - printf("ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \ + fprintf(stderr, "ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_passwd_chat() ); ret = 1; } @@ -159,32 +159,32 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_ } if (strlen(lp_winbind_separator()) != 1) { - printf("ERROR: the 'winbind separator' parameter must be a single character.\n"); + fprintf(stderr,"ERROR: the 'winbind separator' parameter must be a single character.\n"); ret = 1; } if (*lp_winbind_separator() == '+') { - printf("'winbind separator = +' might cause problems with group membership.\n"); + fprintf(stderr,"'winbind separator = +' might cause problems with group membership.\n"); } if (lp_algorithmic_rid_base() < BASE_RID) { /* Try to prevent admin foot-shooting, we can't put algorithmic rids below 1000, that's the 'well known RIDs' on NT */ - printf("'algorithmic rid base' must be equal to or above %lu\n", BASE_RID); + fprintf(stderr,"'algorithmic rid base' must be equal to or above %lu\n", BASE_RID); } if (lp_algorithmic_rid_base() & 1) { - printf("'algorithmic rid base' must be even.\n"); + fprintf(stderr,"'algorithmic rid base' must be even.\n"); } #ifndef HAVE_DLOPEN if (lp_preload_modules()) { - printf("WARNING: 'preload modules = ' set while loading plugins not supported.\n"); + fprintf(stderr,"WARNING: 'preload modules = ' set while loading plugins not supported.\n"); } #endif if (!lp_passdb_backend()) { - printf("ERROR: passdb backend must have a value or be left out\n"); + fprintf(stderr,"ERROR: passdb backend must have a value or be left out\n"); } return ret; @@ -236,27 +236,27 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_ set_local_machine_name(new_local_machine, True); } - dbf = x_stdout; + dbf = x_stderr; DEBUGLEVEL = 2; AllowDebugChange = False; - printf("Load smb config files from %s\n",config_file); + fprintf(stderr,"Load smb config files from %s\n",config_file); if (!lp_load(config_file,False,True,False)) { - printf("Error loading services.\n"); + fprintf(stderr,"Error loading services.\n"); return(1); } - printf("Loaded services file OK.\n"); + fprintf(stderr,"Loaded services file OK.\n"); ret = do_global_checks(); for (s=0;s<1000;s++) { if (VALID_SNUM(s)) if (strlen(lp_servicename(s)) > 12) { - printf( "WARNING: You have some share names that are longer than 12 characters.\n" ); - printf( "These may not be accessible to some older clients.\n" ); - printf( "(Eg. Windows9x, WindowsMe, and smbclient prior to Samba 3.0.)\n" ); + fprintf(stderr, "WARNING: You have some share names that are longer than 12 characters.\n" ); + fprintf(stderr, "These may not be accessible to some older clients.\n" ); + fprintf(stderr, "(Eg. Windows9x, WindowsMe, and smbclient prior to Samba 3.0.)\n" ); break; } } @@ -271,7 +271,7 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_ char *hasstar = strchr_m(deny_list[i], '*'); char *hasquery = strchr_m(deny_list[i], '?'); if(hasstar || hasquery) { - printf("Invalid character %c in hosts deny list (%s) for service %s.\n", + fprintf(stderr,"Invalid character %c in hosts deny list (%s) for service %s.\n", hasstar ? *hasstar : *hasquery, deny_list[i], lp_servicename(s) ); } } @@ -282,35 +282,35 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_ char *hasstar = strchr_m(allow_list[i], '*'); char *hasquery = strchr_m(allow_list[i], '?'); if(hasstar || hasquery) { - printf("Invalid character %c in hosts allow list (%s) for service %s.\n", + fprintf(stderr,"Invalid character %c in hosts allow list (%s) for service %s.\n", hasstar ? *hasstar : *hasquery, allow_list[i], lp_servicename(s) ); } } } if(lp_level2_oplocks(s) && !lp_oplocks(s)) { - printf("Invalid combination of parameters for service %s. \ + fprintf(stderr,"Invalid combination of parameters for service %s. \ Level II oplocks can only be set if oplocks are also set.\n", lp_servicename(s) ); } if (lp_map_hidden(s) && !(lp_create_mask(s) & S_IXOTH)) { - printf("Invalid combination of parameters for service %s. \ + fprintf(stderr,"Invalid combination of parameters for service %s. \ Map hidden can only work if create mask includes octal 01 (S_IXOTH).\n", lp_servicename(s) ); } if (lp_map_hidden(s) && (lp_force_create_mode(s) & S_IXOTH)) { - printf("Invalid combination of parameters for service %s. \ + fprintf(stderr,"Invalid combination of parameters for service %s. \ Map hidden can only work if force create mode excludes octal 01 (S_IXOTH).\n", lp_servicename(s) ); } if (lp_map_system(s) && !(lp_create_mask(s) & S_IXGRP)) { - printf("Invalid combination of parameters for service %s. \ + fprintf(stderr,"Invalid combination of parameters for service %s. \ Map system can only work if create mask includes octal 010 (S_IXGRP).\n", lp_servicename(s) ); } if (lp_map_system(s) && (lp_force_create_mode(s) & S_IXGRP)) { - printf("Invalid combination of parameters for service %s. \ + fprintf(stderr,"Invalid combination of parameters for service %s. \ Map system can only work if force create mode excludes octal 010 (S_IXGRP).\n", lp_servicename(s) ); } @@ -319,29 +319,29 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_ if (!silent_mode) { - printf("Server role: "); + fprintf(stderr,"Server role: "); switch(lp_server_role()) { case ROLE_STANDALONE: - printf("ROLE_STANDALONE\n"); + fprintf(stderr,"ROLE_STANDALONE\n"); break; case ROLE_DOMAIN_MEMBER: - printf("ROLE_DOMAIN_MEMBER\n"); + fprintf(stderr,"ROLE_DOMAIN_MEMBER\n"); break; case ROLE_DOMAIN_BDC: - printf("ROLE_DOMAIN_BDC\n"); + fprintf(stderr,"ROLE_DOMAIN_BDC\n"); break; case ROLE_DOMAIN_PDC: - printf("ROLE_DOMAIN_PDC\n"); + fprintf(stderr,"ROLE_DOMAIN_PDC\n"); break; default: - printf("Unknown -- internal error?\n"); + fprintf(stderr,"Unknown -- internal error?\n"); break; } } if (!cname) { if (!silent_mode) { - printf("Press enter to see a dump of your service definitions\n"); + fprintf(stderr,"Press enter to see a dump of your service definitions\n"); fflush(stdout); getc(stdin); } @@ -354,10 +354,10 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_ if (VALID_SNUM(s)) { if (allow_access(lp_hostsdeny(-1), lp_hostsallow(-1), cname, caddr) && allow_access(lp_hostsdeny(s), lp_hostsallow(s), cname, caddr)) { - printf("Allow connection from %s (%s) to %s\n", + fprintf(stderr,"Allow connection from %s (%s) to %s\n", cname,caddr,lp_servicename(s)); } else { - printf("Deny connection from %s (%s) to %s\n", + fprintf(stderr,"Deny connection from %s (%s) to %s\n", cname,caddr,lp_servicename(s)); } } -- cgit From b0f93e3e656b500d01a97bcace0c5b027996d14d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 02:57:02 +0000 Subject: Fix spelling mistake. (This used to be commit cbd95c5a74bef4a6c8fd54a8fc24a50f11678cb7) --- source3/tests/sysquotas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/tests/sysquotas.c b/source3/tests/sysquotas.c index e83f28e2d0..2aa643326c 100644 --- a/source3/tests/sysquotas.c +++ b/source3/tests/sysquotas.c @@ -1,4 +1,4 @@ -/* this test should find out what quota api is avalable on the os */ +/* this test should find out what quota api is available on the os */ #if defined(HAVE_QUOTACTL_4A) /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */ -- cgit From 3bf7bb2bcd7e18f29b4d0d4f32b9eb747e330fba Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 02:58:32 +0000 Subject: Fix another unused warning. (This used to be commit 9032e6eb2b4c7ed3d0689b95ed318cdf7ec048d7) --- source3/passdb/pdb_gums.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/passdb/pdb_gums.c b/source3/passdb/pdb_gums.c index caf98e648a..5e1e5e392f 100644 --- a/source3/passdb/pdb_gums.c +++ b/source3/passdb/pdb_gums.c @@ -278,6 +278,8 @@ static NTSTATUS gums_getsampwsid(struct pdb_methods *methods, SAM_ACCOUNT *accou Search by rid **************************************************************************/ +#if 0 + static NTSTATUS gums_getsampwrid (struct pdb_methods *methods, SAM_ACCOUNT *account, uint32 rid) { @@ -290,6 +292,7 @@ static NTSTATUS gums_getsampwrid (struct pdb_methods *methods, return NT_STATUS_OK; } +#endif /*************************************************************************** Updates a SAM_ACCOUNT -- cgit From 3c8ecd3af100db81550ed75256350e2e4c66729f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 03:00:33 +0000 Subject: Formatting syncup with 3.0 (This used to be commit 98881672f5c094181be7988b4d39b451f292e423) --- source3/include/includes.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/include/includes.h b/source3/include/includes.h index fba2eabbe1..fe7923cc81 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -1263,10 +1263,14 @@ int smb_xvasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE( /* we need to use __va_copy() on some platforms */ #ifdef HAVE_VA_COPY +#define VA_COPY(dest, src) va_copy(dest, src) +#else +#ifdef HAVE___VA_COPY #define VA_COPY(dest, src) __va_copy(dest, src) #else #define VA_COPY(dest, src) (dest) = (src) #endif +#endif #ifndef HAVE_TIMEGM time_t timegm(struct tm *tm); -- cgit From 088820404b6eca6e0bc3c70547757aa57e65239c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 03:02:31 +0000 Subject: Whitespace syncup with 3.0 (This used to be commit 9746ef376d2a52ef6ef6b84421d6b7e988a6ca13) --- source3/include/passdb.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source3/include/passdb.h b/source3/include/passdb.h index cd9c57a991..8d40bbfd26 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -201,24 +201,24 @@ typedef struct pdb_context { struct pdb_methods *pdb_methods; struct pdb_methods *pwent_methods; - + /* These functions are wrappers for the functions listed above. They may do extra things like re-reading a SAM_ACCOUNT on update */ NTSTATUS (*pdb_setsampwent)(struct pdb_context *, BOOL update); - + void (*pdb_endsampwent)(struct pdb_context *); - + NTSTATUS (*pdb_getsampwent)(struct pdb_context *, SAM_ACCOUNT *user); - + NTSTATUS (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username); - + NTSTATUS (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid); NTSTATUS (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass); - + NTSTATUS (*pdb_update_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass); - + NTSTATUS (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username); /* group mapping functions: to be removed */ -- cgit From b99fb9397f3772a7dec81a4a24c0df8aa9386253 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 31 Oct 2003 03:17:01 +0000 Subject: Merge from 3.0: Revision 1.50.2.12: Put in a work-around for ENOTSUP not being defined on OpenBSD. Revision 1.50.2.10-11 Apply latest of Derrell Lippman's changes to libsmbclient. Commit Derrell's changes to libsmbclient plus a small change to configure.in to see if SGI and other platforms will build. (This used to be commit e32826980eefeb501e4ae19c689d83153d9fe5e6) --- source3/libsmb/libsmbclient.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index a11a965fde..21273ec431 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -40,7 +40,10 @@ #define CREATE_ACCESS_READ READ_CONTROL_ACCESS - +/*We should test for this in configure ... */ +#ifndef ENOTSUP +#define ENOTSUP EOPNOTSUPP +#endif /* * Functions exported by libsmb_cache.c that we need here @@ -610,15 +613,15 @@ SMBCSRV *smbc_server(SMBCCTX *context, * connection. This works similarly to smbc_server(). */ SMBCSRV *smbc_attr_server(SMBCCTX *context, - const char *server, const char *share, - fstring workgroup, - fstring username, fstring password) + const char *server, const char *share, + fstring workgroup, + fstring username, fstring password, + POLICY_HND *pol) { struct in_addr ip; struct cli_state *ipc_cli; NTSTATUS nt_status; SMBCSRV *ipc_srv=NULL; - POLICY_HND pol; /* * See if we've already created this special connection. Reference @@ -666,7 +669,7 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, ipc_cli->mem_ctx, True, GENERIC_EXECUTE_ACCESS, - &pol); + pol); if (!NT_STATUS_IS_OK(nt_status)) { errno = smbc_errno(context, ipc_cli); @@ -3362,7 +3365,8 @@ int smbc_setxattr_ctx(SMBCCTX *context, } ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password); + workgroup, user, password, + &pol); if (!ipc_srv) { return -1; } @@ -3493,7 +3497,8 @@ int smbc_getxattr_ctx(SMBCCTX *context, } ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password); + workgroup, user, password, + &pol); if (!ipc_srv) { return -1; } @@ -3575,13 +3580,15 @@ int smbc_removexattr_ctx(SMBCCTX *context, } ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password); + workgroup, user, password, + &pol); if (!ipc_srv) { return -1; } ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password); + workgroup, user, password, + &pol); if (!ipc_srv) { return -1; } -- cgit From 73a9e080cd5bdd657a3dfd9ba57730060fa344e9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 31 Oct 2003 19:16:57 +0000 Subject: Patch from Aurélien Degrémont . "entry" is dependent on "result", don't free result first. Jeremy. (This used to be commit 9b24715170c6ca5dd3d5df0675f430852ae6a50d) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source3/passdb/pdb_ldap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index e0148494d3..9299ca2e50 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1983,21 +1983,22 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods, return NT_STATUS_UNSUCCESSFUL; } - ldap_msgfree(result); - if (mods == NULL) { DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: nothing to do\n")); + ldap_msgfree(result); return NT_STATUS_OK; } dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry); if (!dn) { + ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; } rc = smbldap_modify(ldap_state->smbldap_state, dn, mods); SAFE_FREE(dn); ldap_mods_free(mods, True); + ldap_msgfree(result); if (rc != LDAP_SUCCESS) { char *ld_error = NULL; @@ -2006,6 +2007,7 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods, DEBUG(0, ("ldapsam_update_group_mapping_entry: failed to modify group %lu error: %s (%s)\n", (unsigned long)map->gid, ld_error ? ld_error : "(unknown)", ldap_err2string(rc))); SAFE_FREE(ld_error); + return NT_STATUS_UNSUCCESSFUL; } DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid)); -- cgit From f943812aae03825c63653ae8885589ac29f900fb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 31 Oct 2003 20:31:25 +0000 Subject: set- set-assword when invoking --set-auth-user and no pw is given (patch from Tom Dickson) (This used to be commit aa2abd5800856120ddec6937955e961ff0c77c96) --- source3/nsswitch/wbinfo.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 0018e99f60..04233bb85c 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -789,8 +789,13 @@ static BOOL wbinfo_set_auth_user(char *username) if (password) { *password = 0; password++; - } else - password = ""; + } else { + char *thepass = getpass("Password: "); + if (thepass) { + password = thepass; + } else + password = ""; + } /* Store or remove DOMAIN\username%password in secrets.tdb */ -- cgit From e45d0f8f466d8abce68517f575ae47893eb7f713 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 1 Nov 2003 17:42:44 +0000 Subject: From 3_0: This binds the nmbd sending socket to the 'socket address'. Hmmm. This is correct in 2.2. Obviously I did not test my 3.0 checkin at that time. Now it hit me at a customer's site... Volker (This used to be commit b9179aed4d7e8ec95e0f8ff79e36403377773f0a) --- source3/nmbd/nmbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 25ba07c8a7..36aa2e2485 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -570,8 +570,8 @@ static BOOL open_sockets(BOOL isdaemon, int port) if ( isdaemon ) ClientNMB = open_socket_in(SOCK_DGRAM, port, - interpret_addr(lp_socket_address()), - 0,True); + 0, interpret_addr(lp_socket_address()), + True); else ClientNMB = 0; -- cgit From b5e7ec9fcccd9599e4161d70092854cde5414569 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 2 Nov 2003 04:16:14 +0000 Subject: Merge of fix for bug 661 from 3.0 (This used to be commit c96d470af8dd9b5782d7c4f3e9fe5fa92f416f77) --- source3/Makefile.in | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index d409723254..73c7235469 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -773,8 +773,9 @@ bin/.dummy: bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(KRB5LIBS) $(LDAP_LIBS) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) \ - $(AUTH_LIBS) $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \ + $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \ + $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@ bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -791,7 +792,9 @@ bin/swat@EXEEXT@: $(SWAT_OBJ) @BUILD_POPT@ bin/.dummy bin/rpcclient@EXEEXT@: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(PASSDB_LIBS) $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \ + $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ \ + $(KRB5LIBS) $(LDAP_LIBS) bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -850,7 +853,8 @@ bin/smbtree@EXEEXT@: $(SMBTREE_OBJ) @BUILD_POPT@ bin/.dummy bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(PASSDB_LIBS) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(PASSDB_LIBS) \ + $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ -- cgit From 1ae80ade5ebfa07cb726c1ce91afdcbfb0f2fea2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 2 Nov 2003 16:31:38 +0000 Subject: Fix duplicate libs problem in iconv detection code. (This used to be commit a2feac08e89685c35a8cc18eaeac4c9316248f75) --- source3/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index bbade6027f..4d1db6f498 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1616,7 +1616,7 @@ dnl Try to find iconv(3) if test "$ICONV_FOUND" = yes; then LIB_ADD_DIR(LDFLAGS, "$i/lib") CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") - LIBS="$save_LIBS $LIBS" + LIBS="$save_LIBS" ICONV_LOCATION=$i export LDFLAGS LIBS CPPFLAGS dnl Now, check for a working iconv ... we want to do it here because -- cgit From 26ec85d00f83257e81c921ddbea8debcfa64ff19 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 3 Nov 2003 18:11:46 +0000 Subject: From 3_0: AC_CHECK_MEMBER seems to have problems for some versions of autoconf, at least autoconf-2.53 on SLES8 does not correctly find the keyblock. Volker (This used to be commit f6cff956c441eec73360f71bbb4dd06f4f1ee897) --- source3/configure.in | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 4d1db6f498..66c3ac171e 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2664,15 +2664,29 @@ if test x"$with_ads_support" != x"no"; then [Whether in-memory keytabs are supported]) fi - AC_CHECK_MEMBER(krb5_keytab_entry.key, - AC_DEFINE(HAVE_KRB5_KEYTAB_ENTRY_KEY, 1, - [Whether krb5_keytab_entry has key member]), [], - [#include ]) - - AC_CHECK_MEMBER(krb5_keytab_entry.keyblock, - AC_DEFINE(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK, 1, - [Whether krb5_keytab_entry has keyblock member]), [], - [#include ]) + AC_CACHE_CHECK([for key in krb5_keytab_entry], + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY,[ + AC_TRY_COMPILE([#include ], + [krb5_keytab_entry entry; entry.key = NULL;], + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY=yes, + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY=no)]) + + if test x"$samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY" = x"yes"; then + AC_DEFINE(HAVE_KRB5_KEYTAB_ENTRY_KEY,1, + [Whether krb5_keytab_entry has key member]) + fi + + AC_CACHE_CHECK([for keyblock in krb5_keytab_entry], + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK,[ + AC_TRY_COMPILE([#include ], + [krb5_keytab_entry entry; entry.keyblock.keytype = 0;], + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK=yes, + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK=no)]) + + if test x"$samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK" = x"yes"; then + AC_DEFINE(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK,1, + [Whether krb5_keytab_entry has keyblock member]) + fi if test x"$ac_cv_lib_ext_krb5_krb5_mk_req_extended" = x"yes"; then AC_DEFINE(HAVE_KRB5,1,[Whether to have KRB5 support]) -- cgit From d789f3bcb5044d381d4702991f4be24727870281 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 3 Nov 2003 19:23:05 +0000 Subject: removing #include in hopes to avoid problems with apache header files; will watch the build farm on this to make sure things don't blow up (This used to be commit b4d80ee74727a72aa8fe070d13e3ca5de71837ca) --- source3/configure.in | 2 +- source3/include/includes.h | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 66c3ac171e..804740b753 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -564,7 +564,7 @@ AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h) AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h net/if.h) -AC_CHECK_HEADERS(compat.h rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h) +AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h) AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/mode.h) AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h) AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h) diff --git a/source3/include/includes.h b/source3/include/includes.h index fe7923cc81..c463f99a90 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -333,10 +333,6 @@ #define PASSWORD_LENGTH 16 #endif /* HAVE_SYS_SECURITY_H */ -#ifdef HAVE_COMPAT_H -#include -#endif - #ifdef HAVE_STROPTS_H #include #endif -- cgit From c8e7fc1fcd988d55ab9480c63109f3665c147962 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 3 Nov 2003 21:05:50 +0000 Subject: Fix for winbindd on HPUX from albert chin (china@thewrittenword.com) Jeremy. (This used to be commit c2f38eb66578affb50cb15c73b297fb866be140b) --- source3/nsswitch/winbind_nss_hpux.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source3/nsswitch/winbind_nss_hpux.h b/source3/nsswitch/winbind_nss_hpux.h index 1f2bade972..d2a5057bf5 100644 --- a/source3/nsswitch/winbind_nss_hpux.h +++ b/source3/nsswitch/winbind_nss_hpux.h @@ -25,10 +25,6 @@ #include -#ifndef _HAVE_TYPEDEF_NSS_STATUS -#define _HAVE_TYPEDEF_NSS_STATUS -typedef nss_status_t NSS_STATUS; - #define NSS_STATUS_SUCCESS NSS_SUCCESS #define NSS_STATUS_NOTFOUND NSS_NOTFOUND #define NSS_STATUS_UNAVAIL NSS_UNAVAIL @@ -48,6 +44,8 @@ typedef enum { NSS_TRYAGAIN } nss_status_t; +typedef nss_status_t NSS_STATUS; + struct nss_backend; typedef nss_status_t (*nss_backend_op_t)(struct nss_backend *, void *args); -- cgit From 3d7fe188813371e2683dc0e47a4a3e14aaf61194 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 3 Nov 2003 23:59:45 +0000 Subject: TDBSAM update code from Aur?lien Degr?mont . Adds support for an additional field (uint32) which represents the lockout duration. I think this should be stored as an abolute UNIX time_t that specifies when the lockout should end - set it when the lockout is imposed. This new code also updates the on disk tdb version on load. Being merged into HEAD so Simo can add any other changes he wants before being back-ported to SAMBA_3_0. Jeremy. (This used to be commit 0eea3f22aba25c1d0a8800bb1725238422cb30eb) --- source3/passdb/passdb.c | 452 +++++++++++++++++++++++++++++++++++++++++++++-- source3/passdb/pdb_tdb.c | 184 ++++++++++++++++++- 2 files changed, 620 insertions(+), 16 deletions(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 9d8f600eea..48f7546394 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1288,13 +1288,29 @@ BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_ Marshall/unmarshall SAM_ACCOUNT structs. *********************************************************************/ -#define TDB_FORMAT_STRING "ddddddBBBBBBBBBBBBddBBwdwdBwwd" +#define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" +#define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" /********************************************************************** Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len *********************************************************************/ BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) +{ + return(init_sam_from_buffer_v1(sampass, buf, buflen)); +} + +/********************************************************************** + Intialize a BYTE buffer from a SAM_ACCOUNT struct + *********************************************************************/ + +uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only) +{ + return(init_buffer_from_sam_v1(buf, sampass, size_only)); +} + + +BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) { /* times are stored as 32bit integer @@ -1338,7 +1354,7 @@ BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) } /* unpack the buffer into variables */ - len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING, + len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0, &logon_time, &logoff_time, &kickoff_time, @@ -1468,11 +1484,425 @@ done: return ret; } -/********************************************************************** - Intialize a BYTE buffer from a SAM_ACCOUNT struct - *********************************************************************/ -uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only) +uint32 init_buffer_from_sam_v0 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only) +{ + size_t len, buflen; + + /* times are stored as 32bit integer + take care on system with 64bit wide time_t + --SSS */ + uint32 logon_time, + logoff_time, + kickoff_time, + pass_last_set_time, + pass_can_change_time, + pass_must_change_time; + + uint32 user_rid, group_rid; + + const char *username; + const char *domain; + const char *nt_username; + const char *dir_drive; + const char *unknown_str; + const char *munged_dial; + const char *fullname; + const char *homedir; + const char *logon_script; + const char *profile_path; + const char *acct_desc; + const char *workstations; + uint32 username_len, domain_len, nt_username_len, + dir_drive_len, unknown_str_len, munged_dial_len, + fullname_len, homedir_len, logon_script_len, + profile_path_len, acct_desc_len, workstations_len; + + const uint8 *lm_pw; + const uint8 *nt_pw; + uint32 lm_pw_len = 16; + uint32 nt_pw_len = 16; + + /* do we have a valid SAM_ACCOUNT pointer? */ + if (sampass == NULL) { + DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n")); + return -1; + } + + *buf = NULL; + buflen = 0; + + logon_time = (uint32)pdb_get_logon_time(sampass); + logoff_time = (uint32)pdb_get_logoff_time(sampass); + kickoff_time = (uint32)pdb_get_kickoff_time(sampass); + pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass); + pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass); + pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass); + + user_rid = pdb_get_user_rid(sampass); + group_rid = pdb_get_group_rid(sampass); + + username = pdb_get_username(sampass); + if (username) + username_len = strlen(username) +1; + else + username_len = 0; + + domain = pdb_get_domain(sampass); + if (domain) + domain_len = strlen(domain) +1; + else + domain_len = 0; + + nt_username = pdb_get_nt_username(sampass); + if (nt_username) + nt_username_len = strlen(nt_username) +1; + else + nt_username_len = 0; + + fullname = pdb_get_fullname(sampass); + if (fullname) + fullname_len = strlen(fullname) +1; + else + fullname_len = 0; + + /* + * Only updates fields which have been set (not defaults from smb.conf) + */ + + if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) + dir_drive = pdb_get_dir_drive(sampass); + else + dir_drive = NULL; + if (dir_drive) + dir_drive_len = strlen(dir_drive) +1; + else + dir_drive_len = 0; + + if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) + homedir = pdb_get_homedir(sampass); + else + homedir = NULL; + if (homedir) + homedir_len = strlen(homedir) +1; + else + homedir_len = 0; + + if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) + logon_script = pdb_get_logon_script(sampass); + else + logon_script = NULL; + if (logon_script) + logon_script_len = strlen(logon_script) +1; + else + logon_script_len = 0; + + if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) + profile_path = pdb_get_profile_path(sampass); + else + profile_path = NULL; + if (profile_path) + profile_path_len = strlen(profile_path) +1; + else + profile_path_len = 0; + + lm_pw = pdb_get_lanman_passwd(sampass); + if (!lm_pw) + lm_pw_len = 0; + + nt_pw = pdb_get_nt_passwd(sampass); + if (!nt_pw) + nt_pw_len = 0; + + acct_desc = pdb_get_acct_desc(sampass); + if (acct_desc) + acct_desc_len = strlen(acct_desc) +1; + else + acct_desc_len = 0; + + workstations = pdb_get_workstations(sampass); + if (workstations) + workstations_len = strlen(workstations) +1; + else + workstations_len = 0; + + unknown_str = NULL; + unknown_str_len = 0; + + munged_dial = pdb_get_munged_dial(sampass); + if (munged_dial) + munged_dial_len = strlen(munged_dial) +1; + else + munged_dial_len = 0; + + /* one time to get the size needed */ + len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V0, + logon_time, + logoff_time, + kickoff_time, + pass_last_set_time, + pass_can_change_time, + pass_must_change_time, + username_len, username, + domain_len, domain, + nt_username_len, nt_username, + fullname_len, fullname, + homedir_len, homedir, + dir_drive_len, dir_drive, + logon_script_len, logon_script, + profile_path_len, profile_path, + acct_desc_len, acct_desc, + workstations_len, workstations, + unknown_str_len, unknown_str, + munged_dial_len, munged_dial, + user_rid, + group_rid, + lm_pw_len, lm_pw, + nt_pw_len, nt_pw, + pdb_get_acct_ctrl(sampass), + pdb_get_unknown_3(sampass), + pdb_get_logon_divs(sampass), + pdb_get_hours_len(sampass), + MAX_HOURS_LEN, pdb_get_hours(sampass), + pdb_get_bad_password_count(sampass), + pdb_get_logon_count(sampass), + pdb_get_unknown_6(sampass)); + + + if (size_only) + return buflen; + + /* malloc the space needed */ + if ( (*buf=(uint8*)malloc(len)) == NULL) { + DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n")); + return (-1); + } + + /* now for the real call to tdb_pack() */ + buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V0, + logon_time, + logoff_time, + kickoff_time, + pass_last_set_time, + pass_can_change_time, + pass_must_change_time, + username_len, username, + domain_len, domain, + nt_username_len, nt_username, + fullname_len, fullname, + homedir_len, homedir, + dir_drive_len, dir_drive, + logon_script_len, logon_script, + profile_path_len, profile_path, + acct_desc_len, acct_desc, + workstations_len, workstations, + unknown_str_len, unknown_str, + munged_dial_len, munged_dial, + user_rid, + group_rid, + lm_pw_len, lm_pw, + nt_pw_len, nt_pw, + pdb_get_acct_ctrl(sampass), + pdb_get_unknown_3(sampass), + pdb_get_logon_divs(sampass), + pdb_get_hours_len(sampass), + MAX_HOURS_LEN, pdb_get_hours(sampass), + pdb_get_bad_password_count(sampass), + pdb_get_logon_count(sampass), + pdb_get_unknown_6(sampass)); + + + /* check to make sure we got it correct */ + if (buflen != len) { + DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n", + (unsigned long)buflen, (unsigned long)len)); + /* error */ + SAFE_FREE (*buf); + return (-1); + } + + return (buflen); +} + + +BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) +{ + + /* times are stored as 32bit integer + take care on system with 64bit wide time_t + --SSS */ + uint32 logon_time, + logoff_time, + kickoff_time, + lockout_time, + pass_last_set_time, + pass_can_change_time, + pass_must_change_time; + char *username; + char *domain; + char *nt_username; + char *dir_drive; + char *unknown_str; + char *munged_dial; + char *fullname; + char *homedir; + char *logon_script; + char *profile_path; + char *acct_desc; + char *workstations; + uint32 username_len, domain_len, nt_username_len, + dir_drive_len, unknown_str_len, munged_dial_len, + fullname_len, homedir_len, logon_script_len, + profile_path_len, acct_desc_len, workstations_len; + + uint32 user_rid, group_rid, unknown_3, hours_len, unknown_6; + uint16 acct_ctrl, logon_divs; + uint16 bad_password_count, logon_count; + uint8 *hours; + static uint8 *lm_pw_ptr, *nt_pw_ptr; + uint32 len = 0; + uint32 lm_pw_len, nt_pw_len, hourslen; + BOOL ret = True; + + if(sampass == NULL || buf == NULL) { + DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n")); + return False; + } + + /* unpack the buffer into variables */ + len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1, + &logon_time, + &logoff_time, + &kickoff_time, + &lockout_time, + &pass_last_set_time, + &pass_can_change_time, + &pass_must_change_time, + &username_len, &username, + &domain_len, &domain, + &nt_username_len, &nt_username, + &fullname_len, &fullname, + &homedir_len, &homedir, + &dir_drive_len, &dir_drive, + &logon_script_len, &logon_script, + &profile_path_len, &profile_path, + &acct_desc_len, &acct_desc, + &workstations_len, &workstations, + &unknown_str_len, &unknown_str, + &munged_dial_len, &munged_dial, + &user_rid, + &group_rid, + &lm_pw_len, &lm_pw_ptr, + &nt_pw_len, &nt_pw_ptr, + &acct_ctrl, + &unknown_3, + &logon_divs, + &hours_len, + &hourslen, &hours, + &bad_password_count, + &logon_count, + &unknown_6); + + if (len == -1) { + ret = False; + goto done; + } + + pdb_set_logon_time(sampass, logon_time, PDB_SET); + pdb_set_logoff_time(sampass, logoff_time, PDB_SET); + pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); + pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET); + pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET); + pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET); + + pdb_set_username(sampass, username, PDB_SET); + pdb_set_domain(sampass, domain, PDB_SET); + pdb_set_nt_username(sampass, nt_username, PDB_SET); + pdb_set_fullname(sampass, fullname, PDB_SET); + + if (homedir) { + pdb_set_homedir(sampass, homedir, PDB_SET); + } + else { + pdb_set_homedir(sampass, + talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()), + PDB_DEFAULT); + } + + if (dir_drive) + pdb_set_dir_drive(sampass, dir_drive, PDB_SET); + else { + pdb_set_dir_drive(sampass, + talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()), + PDB_DEFAULT); + } + + if (logon_script) + pdb_set_logon_script(sampass, logon_script, PDB_SET); + else { + pdb_set_logon_script(sampass, + talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()), + PDB_DEFAULT); + } + + if (profile_path) { + pdb_set_profile_path(sampass, profile_path, PDB_SET); + } else { + pdb_set_profile_path(sampass, + talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()), + PDB_DEFAULT); + } + + pdb_set_acct_desc(sampass, acct_desc, PDB_SET); + pdb_set_workstations(sampass, workstations, PDB_SET); + pdb_set_munged_dial(sampass, munged_dial, PDB_SET); + + if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) { + if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) { + ret = False; + goto done; + } + } + + if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) { + if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) { + ret = False; + goto done; + } + } + + pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); + pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET); + pdb_set_unknown_3(sampass, unknown_3, PDB_SET); + pdb_set_hours_len(sampass, hours_len, PDB_SET); + pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); + pdb_set_logon_count(sampass, logon_count, PDB_SET); + pdb_set_unknown_6(sampass, unknown_6, PDB_SET); + pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET); + pdb_set_logon_divs(sampass, logon_divs, PDB_SET); + pdb_set_hours(sampass, hours, PDB_SET); + +done: + + SAFE_FREE(username); + SAFE_FREE(domain); + SAFE_FREE(nt_username); + SAFE_FREE(fullname); + SAFE_FREE(homedir); + SAFE_FREE(dir_drive); + SAFE_FREE(logon_script); + SAFE_FREE(profile_path); + SAFE_FREE(acct_desc); + SAFE_FREE(workstations); + SAFE_FREE(munged_dial); + SAFE_FREE(unknown_str); + SAFE_FREE(hours); + + return ret; +} + + +uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only) { size_t len, buflen; @@ -1482,6 +1912,7 @@ uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_ uint32 logon_time, logoff_time, kickoff_time, + lockout_time, pass_last_set_time, pass_can_change_time, pass_must_change_time; @@ -1522,6 +1953,7 @@ uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_ logon_time = (uint32)pdb_get_logon_time(sampass); logoff_time = (uint32)pdb_get_logoff_time(sampass); kickoff_time = (uint32)pdb_get_kickoff_time(sampass); + lockout_time = (uint32)0; pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass); pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass); pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass); @@ -1623,10 +2055,11 @@ uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_ munged_dial_len = 0; /* one time to get the size needed */ - len = tdb_pack(NULL, 0, TDB_FORMAT_STRING, + len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V1, logon_time, logoff_time, kickoff_time, + lockout_time, pass_last_set_time, pass_can_change_time, pass_must_change_time, @@ -1666,10 +2099,11 @@ uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_ } /* now for the real call to tdb_pack() */ - buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING, + buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V1, logon_time, logoff_time, kickoff_time, + lockout_time, pass_last_set_time, pass_can_change_time, pass_must_change_time, @@ -1756,5 +2190,3 @@ BOOL get_free_rid_range(uint32 *low, uint32 *high) return True; } - - diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index c9a84f3242..966682563c 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -37,10 +37,12 @@ static int tdbsam_debug_level = DBGC_ALL; #endif +#define TDBSAM_VERSION 1 /* Most recent TDBSAM version */ #define PDB_VERSION "20010830" #define PASSDB_FILE_NAME "passdb.tdb" #define USERPREFIX "USER_" #define RIDPREFIX "RID_" +#define tdbsamver_t int32 struct tdbsam_privates { TDB_CONTEXT *passwd_tdb; @@ -50,6 +52,176 @@ struct tdbsam_privates { const char *tdbsam_location; }; +/** + * Convert old TDBSAM to the latest version. + * @param pdb_tdb A pointer to the opened TDBSAM file which must be converted. + * This file must be opened with read/write access. + * @param from Current version of the TDBSAM file. + * @return True if the conversion has been successful, false otherwise. + **/ + +static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from) +{ + const char * vstring = "INFO/version"; + SAM_ACCOUNT *user = NULL; + const char *prefix = USERPREFIX; + TDB_DATA data, key, old_key; + uint8 *buf = NULL; + BOOL ret; + + if (pdb_tdb == NULL) { + DEBUG(0,("tdbsam_convert: Bad TDB Context pointer.\n")); + return False; + } + + /* handle a Samba upgrade */ + tdb_lock_bystring(pdb_tdb, vstring, 0); + + if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) { + DEBUG(0,("tdbsam_convert: cannot initialized a SAM_ACCOUNT.\n")); + return False; + } + + /* Enumerate all records and convert them */ + key = tdb_firstkey(pdb_tdb); + + while (key.dptr) { + + /* skip all non-USER entries (eg. RIDs) */ + while ((key.dsize != 0) && (strncmp(key.dptr, prefix, strlen (prefix)))) { + old_key = key; + /* increment to next in line */ + key = tdb_nextkey(pdb_tdb, key); + SAFE_FREE(old_key.dptr); + } + + if (key.dptr) { + + /* read from tdbsam */ + data = tdb_fetch(pdb_tdb, key); + if (!data.dptr) { + DEBUG(0,("tdbsam_convert: database entry not found: %s.\n",key.dptr)); + return False; + } + + if (!NT_STATUS_IS_OK(pdb_reset_sam(user))) { + DEBUG(0,("tdbsam_convert: cannot reset SAM_ACCOUNT.\n")); + SAFE_FREE(data.dptr); + return False; + } + + /* unpack the buffer from the former format */ + DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) (version:%d)\n", key.dptr, from)); + switch (from) { + case 0: + ret = init_sam_from_buffer_v0(user, (uint8 *)data.dptr, data.dsize); + break; + case 1: + ret = init_sam_from_buffer_v1(user, (uint8 *)data.dptr, data.dsize); + break; + default: + /* unknown tdbsam version */ + ret = False; + } + if (!ret) { + DEBUG(0,("tdbsam_convert: Bad SAM_ACCOUNT entry returned from TDB (key:%s) (version:%d)\n", key.dptr, from)); + SAFE_FREE(data.dptr); + return False; + } + + /* pack from the buffer into the new format */ + DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from)); + if ((data.dsize=init_buffer_from_sam (&buf, user, False)) == -1) { + DEBUG(0,("tdbsam_convert: cannot pack the SAM_ACCOUNT into the new format\n")); + SAFE_FREE(data.dptr); + return False; + } + data.dptr = (char *)buf; + + /* Store the buffer inside the TDBSAM */ + if (tdb_store(pdb_tdb, key, data, TDB_MODIFY) != TDB_SUCCESS) { + DEBUG(0,("tdbsam_convert: cannot store the SAM_ACCOUNT (key:%s) in new format\n",key.dptr)); + SAFE_FREE(data.dptr); + return False; + } + + SAFE_FREE(data.dptr); + + /* increment to next in line */ + old_key = key; + key = tdb_nextkey(pdb_tdb, key); + SAFE_FREE(old_key.dptr); + } + + } + + pdb_free_sam(&user); + + /* upgrade finished */ + tdb_store_int32(pdb_tdb, vstring, TDBSAM_VERSION); + tdb_unlock_bystring(pdb_tdb, vstring); + + return(True); +} + +/** + * Open the TDB passwd database, check version and convert it if needed. + * @param name filename of the tdbsam file. + * @param open_flags file access mode. + * @return a TDB_CONTEXT handle on the tdbsam file. + **/ + +static TDB_CONTEXT * tdbsam_tdbopen (const char *name, int open_flags) +{ + TDB_CONTEXT *pdb_tdb; + tdbsamver_t version; + + /* Try to open tdb passwd */ + if (!(pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, open_flags, 0600))) + return NULL; + + /* Check the version */ + version = (tdbsamver_t) tdb_fetch_int32(pdb_tdb, "INFO/version"); + if (version == -1) + version = 0; /* Version not found, assume version 0 */ + + /* Compare the version */ + if (version > TDBSAM_VERSION) { + /* Version more recent than the latest known */ + DEBUG(0, ("TDBSAM version unknown: %d\n", version)); + tdb_close(pdb_tdb); + pdb_tdb = NULL; + } + else if (version < TDBSAM_VERSION) { + /* Older version, must be converted */ + DEBUG(1, ("TDBSAM version too old (%d), trying to convert it.\n", version)); + + /* Reopen the pdb file with read-write access if needed */ + if (!(open_flags & O_RDWR)) { + DEBUG(10, ("tdbsam_tdbopen: TDB file opened with read only access, reopen it with read-write access.\n")); + tdb_close(pdb_tdb); + pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, (open_flags & 07777770) | O_RDWR, 0600); + } + + /* Convert */ + if (!tdbsam_convert(pdb_tdb, version)){ + DEBUG(0, ("tdbsam_tdbopen: Error when trying to convert tdbsam: %s\n",name)); + tdb_close(pdb_tdb); + pdb_tdb = NULL; + } else { + DEBUG(1, ("TDBSAM converted successfully.\n")); + } + + /* Reopen the pdb file as it must be */ + if (!(open_flags & O_RDWR)) { + tdb_close(pdb_tdb); + pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, open_flags, 0600); + } + } + + return pdb_tdb; +} + /*************************************************************** Open the TDB passwd database for SAM account enumeration. ****************************************************************/ @@ -59,7 +231,7 @@ static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update) struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; /* Open tdb passwd */ - if (!(tdb_state->passwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, update?(O_RDWR|O_CREAT):O_RDONLY, 0600))) + if (!(tdb_state->passwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, update?(O_RDWR|O_CREAT):O_RDONLY))) { DEBUG(0, ("Unable to open/create TDB passwd\n")); return NT_STATUS_UNSUCCESSFUL; @@ -179,7 +351,7 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT key.dsize = strlen(keystr) + 1; /* open the accounts TDB */ - if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) { + if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY))) { if (errno == ENOENT) { /* @@ -251,7 +423,7 @@ static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT key.dsize = strlen (keystr) + 1; /* open the accounts TDB */ - if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) { + if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY))) { DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n")); return nt_status; } @@ -265,6 +437,7 @@ static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT return nt_status; } + fstrcpy(name, data.dptr); SAFE_FREE(data.dptr); @@ -299,7 +472,7 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_AC strlower_m(name); /* open the TDB */ - if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR, 0600))) { + if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR))) { DEBUG(0, ("Unable to open TDB passwd!")); return nt_status; } @@ -363,7 +536,7 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, /* open the account TDB passwd*/ - pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600); + pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT); if (!pwd_tdb) { DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", @@ -519,4 +692,3 @@ NTSTATUS pdb_tdbsam_init(void) { return smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam", pdb_init_tdbsam); } - -- cgit From 7b64564fbeb32d4b1cd0f01c3cdb35953c9c4cff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Nov 2003 18:24:30 +0000 Subject: Fix for bug #703, try lowercase netgroups lookups. Jeremy. (This used to be commit b7ce6294bbff9ef82b34d900fe836ff2e3c5abe1) --- source3/lib/username.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/source3/lib/username.c b/source3/lib/username.c index 6321d47021..40327f8168 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -293,13 +293,16 @@ struct passwd *Get_Pwnam(const char *user) } /**************************************************************************** - Check if a user is in a netgroup user list. + Check if a user is in a netgroup user list. If at first we don't succeed, + try lower case. ****************************************************************************/ static BOOL user_in_netgroup_list(const char *user, const char *ngname) { #ifdef HAVE_NETGROUP static char *mydomain = NULL; + fstring lowercase_user, lowercase_ngname; + if (mydomain == NULL) yp_get_default_domain(&mydomain); @@ -315,6 +318,20 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname) if (innetgr(ngname, NULL, user, mydomain)) return (True); + + /* + * 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); + fstrcpy(lowercase_ngname, ngname); + strlower_m(lowercase_ngname); + + if (innetgr(lowercase_ngname, NULL, lowercase_user, mydomain)) + return (True); + #endif /* HAVE_NETGROUP */ return False; } -- cgit From 0c94d59205c92771b5091480b774794aefbe6b0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Nov 2003 00:12:53 +0000 Subject: Fix for bug #771. Fix packet length for browse list reply. Jeremy. (This used to be commit dfea28a7731a0625e37ac43658f21b25e2fcce21) --- source3/nmbd/nmbd_packets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c index 72eb1b5019..c318689fd1 100644 --- a/source3/nmbd/nmbd_packets.c +++ b/source3/nmbd/nmbd_packets.c @@ -1835,7 +1835,7 @@ BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len, /* Setup the smb part. */ ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ memcpy(tmp,ptr,4); - set_message(ptr,17,23 + len,True); + set_message(ptr,17,strlen(mailslot) + 1 + len,True); memcpy(ptr,tmp,4); SCVAL(ptr,smb_com,SMBtrans); -- cgit From 7c92ebb50279f9d00a10a1155f11b30230c79283 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Nov 2003 00:17:17 +0000 Subject: Fix coredump in cli_get_backup_list. Jeremy. (This used to be commit 13d32f561b23f2d69daf103a971acbdae547703d) --- source3/libsmb/clidgram.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 5ab6bef87b..c4675f1938 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -75,7 +75,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot, SSVAL(ptr,smb_vwv15,1); SSVAL(ptr,smb_vwv16,2); p2 = smb_buf(ptr); - pstrcpy(p2,mailslot); + fstrcpy(p2,mailslot); p2 = skip_string(p2,1); memcpy(p2,buf,len); @@ -135,7 +135,7 @@ static char cli_backup_list[1024]; int cli_get_backup_list(const char *myname, const char *send_to_name) { - char outbuf[15]; + pstring outbuf; char *p; struct in_addr sendto_ip, my_ip; int dgram_sock; @@ -262,6 +262,3 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam return True; } - - - -- cgit From 34bbe8d2d30cde6195afa7a18376bf1281aeac8c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 5 Nov 2003 04:17:57 +0000 Subject: added note about stripping comments from LDIF; bug 642 (This used to be commit 41aefed932df1938c5e6681c809150068a39292a) --- examples/LDAP/convertSambaAccount | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/LDAP/convertSambaAccount b/examples/LDAP/convertSambaAccount index e00d0a2326..4357dbc8f8 100755 --- a/examples/LDAP/convertSambaAccount +++ b/examples/LDAP/convertSambaAccount @@ -9,6 +9,12 @@ ## --input= --output= \ ## --changetype=[modify|add] ## +## You can generate an input ldif file using: +## $ ldapsearch -LL -x -h ldapsrv -D cn=root,dc=company,dc=com \ +## -b dc=copmany,dc=com > /tmp/samba3.alpha23.ldif +## +## Note the "-LL" so no additional comments are generated +## use strict; -- cgit From 3d6f7800106a6f5356c19f413f50d43de74a4b8f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 5 Nov 2003 04:34:44 +0000 Subject: make sure that we expand %H (from vl); bug 612 (This used to be commit d1cf39e2ecee7e76953a5eee386f723a46bf9b14) --- source3/lib/substitute.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index 6e546bc161..923afd989f 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -529,6 +529,9 @@ char *alloc_sub_basic(const char *smb_name, const char *str) else t = realloc_string_sub(t, "%L", global_myname()); break; + case 'N': + t = realloc_string_sub(t, "%N", automount_server(smb_name)); + break; case 'M' : t = realloc_string_sub(t, "%M", client_name()); break; -- cgit From 018a3cc5080efd3c26ad8c04036ed367969f700d Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 5 Nov 2003 16:58:25 +0000 Subject: Apply the changes that Derrell Lipman supplied ... (This used to be commit 600e056a33bd658a8e0eb41af9c83d32b9e2e082) --- examples/libsmbclient/tree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/libsmbclient/tree.c b/examples/libsmbclient/tree.c index 8dc9cc408b..f50b3670cf 100644 --- a/examples/libsmbclient/tree.c +++ b/examples/libsmbclient/tree.c @@ -706,9 +706,9 @@ int main( int argc, /* Now, build the top level display ... */ - if ((dh = smbc_opendir("smb:///")) < 0) { + if ((dh = smbc_opendir("smb://")) < 0) { - fprintf(stderr, "Could not list default workgroup: smb:///: %s\n", + fprintf(stderr, "Could not list workgroups: smb://: %s\n", strerror(errno)); exit(1); -- cgit From 930245a0bc29bd548933787a7e17706aad1cbcb8 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Nov 2003 17:17:35 +0000 Subject: Merge from 3.0: Revision 1.468.2.193: Add ldaplibs to pdbedit link line. Fixes bug #651. (This used to be commit 079e00d1030130943791acd54b2af6036891c534) --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 73c7235469..17cf54fa53 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -858,7 +858,7 @@ bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) + @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(LDAP_LIBS) bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ -- cgit From c4029527ef5d30d613e4c47f12fa5574eb9f0eb6 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Nov 2003 17:18:46 +0000 Subject: Merge from 3.0: Revision 1.209.2.44: Fix crash bug in smbclient completion. Closes bug #659. (This used to be commit decc5d9a2525176c70a17d8928587889f5f6e6af) --- source3/client/client.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index ecece8942e..5ee6913374 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2403,10 +2403,9 @@ static char **completion_fn(const char *text, int start, int end) return matches; cleanup: - while (i >= 0) { + for (i = 0; i < count; i++) free(matches[i]); - i--; - } + free(matches); return NULL; } -- cgit From 8e7a77157778d187c25a65c76a4382e60758bccb Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Nov 2003 17:19:48 +0000 Subject: Merge of uname cleanups from 3.0 (This used to be commit e7e17e6b4a6727088b0ea763db673de8035f2094) --- source3/configure.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 804740b753..0a6005b28f 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -266,19 +266,19 @@ if test x"$samba_cv_volatile" = x"yes"; then AC_DEFINE(HAVE_VOLATILE, 1, [Whether the C compiler understands volatile]) fi -UNAME_S=`uname -s` +UNAME_S=`(uname -s) 2>/dev/null` || UNAME_S="unknown" AC_MSG_CHECKING(uname -s) AC_MSG_RESULT(${UNAME_S}) -UNAME_R=`uname -r` +UNAME_R=`(uname -r) 2>/dev/null` || UNAME_R="unknown" AC_MSG_CHECKING(uname -r) AC_MSG_RESULT(${UNAME_R}) -UNAME_M=`uname -m` +UNAME_M=`(uname -m) 2>/dev/null` || UNAME_M="unknown" AC_MSG_CHECKING(uname -m) AC_MSG_RESULT(${UNAME_M}) -UNAME_P=`uname -p` +UNAME_P=`(uname -p) 2>/dev/null` || UNAME_P="unknown" AC_MSG_CHECKING(uname -p) AC_MSG_RESULT(${UNAME_P}) -- cgit From 41847b388f0eff3b6fdd0b304eeec0c31475eb6d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Nov 2003 17:21:22 +0000 Subject: Merge from 3.0: Revision 1.16.2.6: Add prototype for smbc_remove_unused_server() to fix compiler warning. Bug #706. (This used to be commit 99f70d86fe17ce39d803fa23a135169e24d8a34e) --- source3/include/libsmbclient.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index afcafeed81..68c4a053d1 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -1932,5 +1932,16 @@ int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn); */ int smbc_unlink_print_job(const char *purl, int id); +/**@ingroup callback + * Remove a server from the cached server list it's unused. + * + * @param context pointer to smb context + * + * @param srv pointer to server to remove + * + * @return On success, 0 is returned. 1 is returned if the server could not + * be removed. Also useable outside libsmbclient. + */ +int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv); #endif /* SMBCLIENT_H_INCLUDED */ -- cgit From 0467255bfed3c80eb1fcbc0ffc17cffb36c6dbfc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Nov 2003 17:26:43 +0000 Subject: Merge from 3.0: Revision 1.10.2.6: Cast to fix warning on Solaris sendfile - check buildfarm output to see if this works! Bug #706. (This used to be commit 06c4fc35a7226e719c2748b818ecf4e18dd1a4fb) --- source3/lib/sendfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/sendfile.c b/source3/lib/sendfile.c index bcc8cb08ca..4aa76a0c74 100644 --- a/source3/lib/sendfile.c +++ b/source3/lib/sendfile.c @@ -161,7 +161,7 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of vec[0].sfv_fd = SFV_FD_SELF; vec[0].sfv_flag = 0; - vec[0].sfv_off = header->data; + vec[0].sfv_off = (off_t)header->data; vec[0].sfv_len = hdr_len = header->length; vec[1].sfv_fd = fromfd; -- cgit From b216846e8f489e1934b457ebd2bfb1a5b4ae62e4 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Nov 2003 17:28:18 +0000 Subject: Merge from 3.0: Revision 1.42.2.8: Use the actual size of the buffer in strftime instead of a made up value which just happens to be less than sizeof(fstring). Closes #713. (This used to be commit 45c28f8a2723b5e942d13d1c6e5db757921fb64f) --- source3/lib/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/time.c b/source3/lib/time.c index 74ca56bdc5..635ede9be2 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -694,7 +694,7 @@ char *timestring(BOOL hires) ".%06ld", (long)tp.tv_usec); } else { - strftime(TimeBuf,100,"%Y/%m/%d %H:%M:%S",tm); + strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %H:%M:%S",tm); } #else if (hires) { -- cgit From 3c31d65d76fc84bfa0fc86c6b775b5afd1f15097 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Nov 2003 17:32:38 +0000 Subject: Merge of setenv->putenv for winbind client. (This used to be commit a26d425f93e43641195d0aaf0f9ce5ef0e69f5e1) --- source3/nsswitch/wb_common.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c index f146391653..40221b69fe 100644 --- a/source3/nsswitch/wb_common.c +++ b/source3/nsswitch/wb_common.c @@ -472,17 +472,23 @@ NSS_STATUS winbindd_request(int req_type, } /************************************************************************* - A couple of simple jfunctions to disable winbindd lookups and re- + A couple of simple functions to disable winbindd lookups and re- enable them ************************************************************************/ +/* Use putenv() instead of setenv() in these functions as not all + environments have the latter. */ + BOOL winbind_off( void ) { - return (setenv( WINBINDD_DONT_ENV, "1", 1 ) != -1); + static char *s = WINBINDD_DONT_ENV "=1"; + + return putenv(s) != -1; } BOOL winbind_on( void ) { - return (setenv( WINBINDD_DONT_ENV, "0", 1 ) != -1); -} + static char *s = WINBINDD_DONT_ENV "=0"; + return putenv(s) != -1; +} -- cgit From 596783105bc16d6fe768f2fc60f4caec5791058d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Nov 2003 17:34:33 +0000 Subject: Merge of some compiler warning fixes. (This used to be commit 6a001dbd13c11f22b5d3c444fd1da3055f3afb67) --- source3/rpc_parse/parse_prs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index b30c41c090..9056348239 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -1458,7 +1458,7 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags, static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE; static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE; - const uchar *netsec_sig; + const uchar *netsec_sig = NULL; DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len)); @@ -1533,7 +1533,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags, static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE; static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE; - const uchar *netsec_sig; + const uchar *netsec_sig = NULL; uchar seq_num[8]; -- cgit From 5033b016caafadc5aae5f2e8838d08efdfcb5e61 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Nov 2003 17:37:08 +0000 Subject: Merge from 3.0: Revision 1.82.2.24: Patch from James Henstridge to allow rpcclient adddriver command to specify printer driver version. Closes bug #514. (This used to be commit b873832e33ba251741ae4f091f93f4bb79d57bee) --- source3/rpcclient/cmd_spoolss.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index eca31ae444..798949fae9 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1266,12 +1266,13 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli, fstring driver_name; /* parse the command arguements */ - if (argc != 3) + if (argc != 3 && argc != 4) { - printf ("Usage: %s \\\n", argv[0]); + printf ("Usage: %s \\\n", argv[0]); printf ("\t:::\\\n"); printf ("\t:::\\\n"); - printf ("\t:\n"); + printf ("\t: \\\n"); + printf ("\t[version]\n"); return WERR_OK; } @@ -1292,6 +1293,14 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli, return WERR_INVALID_PARAM; } + /* if printer driver version specified, override the default version + * used by the architecture. This allows installation of Windows + * 2000 (version 3) printer drivers. */ + if (argc == 4) + { + info3.version = atoi(argv[3]); + } + ctr.info3 = &info3; result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr); -- cgit From 150fb8ea588d012a31837884d2843ad3040ce0c9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 5 Nov 2003 17:39:24 +0000 Subject: Compile tdbdump by default. Volker (This used to be commit 11da19dd5c2a6434b73a03eadedb5b877776b1f7) --- source3/Makefile.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 17cf54fa53..f7e13220c4 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -126,7 +126,7 @@ SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ @EXTRA_SBIN_PROG BIN_PROGS1 = bin/smbclient@EXEEXT@ bin/net@EXEEXT@ bin/smbspool@EXEEXT@ \ bin/testparm@EXEEXT@ bin/testprns@EXEEXT@ bin/smbstatus@EXEEXT@ BIN_PROGS2 = bin/smbcontrol@EXEEXT@ bin/smbtree@EXEEXT@ bin/tdbbackup@EXEEXT@ \ - bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@ + bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@ bin/tdbdump@EXEEXT@ BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \ bin/profiles@EXEEXT@ bin/ntlm_auth@EXEEXT@ \ bin/smbcquotas@EXEEXT@ @@ -645,6 +645,8 @@ POPT_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \ TDBBACKUP_OBJ = tdb/tdbbackup.o tdb/tdbback.o lib/snprintf.o $(TDBBASE_OBJ) +TDBDUMP_OBJ = tdb/tdbdump.o $(TDBBASE_OBJ) + NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \ libads/kerberos_verify.o $(SECRETS_OBJ) lib/server_mutex.o \ @@ -1174,6 +1176,10 @@ bin/tdbbackup@EXEEXT@: $(TDBBACKUP_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(TDBBACKUP_OBJ) +bin/tdbdump@EXEEXT@: $(TDBDUMP_OBJ) bin/.dummy + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(TDBDUMP_OBJ) + bin/t_strcmp@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o $(CC) $(FLAGS) -o $@ $(LIBS) torture/t_strcmp.o -L ./bin -lbigballofmud -- cgit From f59bd268945960ddd90fccf7cf7b077e1bdf41f2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Nov 2003 18:28:29 +0000 Subject: Merge of 64-bit printf warning fixes. (This used to be commit a6cc763333943bc6e360bb7e78cf9bfb1bc936e8) --- source3/lib/util.c | 3 ++- source3/lib/util_sock.c | 11 ++++++----- source3/lib/util_str.c | 5 +++-- source3/libsmb/ntlmssp_sign.c | 4 ++-- source3/printing/nt_printing.c | 16 ++++++++-------- source3/printing/print_generic.c | 2 +- source3/rpc_server/srv_lsa_hnd.c | 4 ++-- source3/rpc_server/srv_pipe_hnd.c | 2 +- source3/smbd/fileio.c | 6 +++--- source3/smbd/nttrans.c | 8 ++++---- source3/smbd/oplock_linux.c | 4 ++-- source3/smbd/posix_acls.c | 2 +- source3/smbd/process.c | 2 +- source3/smbd/statcache.c | 4 ++-- 14 files changed, 38 insertions(+), 35 deletions(-) diff --git a/source3/lib/util.c b/source3/lib/util.c index 766c5041b4..ce1389c8e9 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1404,7 +1404,8 @@ void smb_panic(const char *why) backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE); backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size); - DEBUG(0, ("BACKTRACE: %d stack frames:\n", backtrace_size)); + DEBUG(0, ("BACKTRACE: %lu stack frames:\n", + (unsigned long)backtrace_size)); if (backtrace_strings) { int i; diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index eb19caa31b..b59d7aa7eb 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -184,8 +184,8 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len) lastip = sock.sin_addr; lastport = ntohs(sock.sin_port); - DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n", - inet_ntoa(lastip), lastport, ret)); + DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %lu\n", + inet_ntoa(lastip), lastport, (unsigned long)ret)); return(ret); } @@ -460,7 +460,7 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int DEBUG(5,("Got keepalive packet\n")); } - DEBUG(10,("got smb length of %d\n",len)); + DEBUG(10,("got smb length of %lu\n",(unsigned long)len)); return(len); } @@ -487,7 +487,8 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) break; } - DEBUG(10,("read_smb_length: got smb length of %d\n",len)); + DEBUG(10,("read_smb_length: got smb length of %lu\n", + (unsigned long)len)); return len; } @@ -529,7 +530,7 @@ BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout) */ if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { - DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); + DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len)); if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { /* diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 15ac1639a9..b6025a362d 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -590,8 +590,9 @@ char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_ len = strnlen(src, maxlength+1); if (len > maxlength) { - DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n", - (unsigned int)(len-maxlength), len, maxlength, src)); + DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n", + (unsigned long)(len-maxlength), (unsigned long)len, + (unsigned long)maxlength, src)); len = maxlength; } diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index ff2f97c2e8..153c234d1f 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -169,8 +169,8 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, NTSTATUS nt_status; if (sig->length < 8) { - DEBUG(0, ("NTLMSSP packet check failed due to short signature (%u bytes)!\n", - sig->length)); + DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n", + (unsigned long)sig->length)); } nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 0b4fa93b5a..f3c3a0389a 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -739,8 +739,8 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */ if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) { - DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n", - fname, byte_count)); + DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n", + fname, (unsigned long)byte_count)); goto no_version_info; } @@ -760,8 +760,8 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 } if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) { - DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n", - fname, byte_count)); + DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %lu\n", + fname, (unsigned long)byte_count)); /* Assume this isn't an error... the file just looks sort of like a PE/NE file */ goto no_version_info; } @@ -794,8 +794,8 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 } if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) { - DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n", - fname, byte_count)); + DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %lu\n", + fname, (unsigned long)byte_count)); goto error_exit; } @@ -825,8 +825,8 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 } if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) { - DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n", - fname, byte_count)); + DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %lu\n", + fname, (unsigned long)byte_count)); goto error_exit; } diff --git a/source3/printing/print_generic.c b/source3/printing/print_generic.c index 0b062ebdd9..1c847448da 100644 --- a/source3/printing/print_generic.c +++ b/source3/printing/print_generic.c @@ -164,7 +164,7 @@ static int generic_job_submit(int snum, struct printjob *pjob) pstrcpy(jobname, pjob->jobname); pstring_sub(jobname, "'", "_"); slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count); - slprintf(job_size, sizeof(job_size)-1, "%d", pjob->size); + slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size); /* send it to the system spooler */ ret = print_run_command(snum, diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c index 814fa60aab..2ec62e2c57 100644 --- a/source3/rpc_server/srv_lsa_hnd.c +++ b/source3/rpc_server/srv_lsa_hnd.c @@ -89,8 +89,8 @@ BOOL init_pipe_handle_list(pipes_struct *p, char *pipe_name) p->pipe_handles = hl; - DEBUG(10,("init_pipe_handles: pipe_handles ref count = %u for pipe %s\n", - p->pipe_handles->pipe_ref_count, pipe_name )); + DEBUG(10,("init_pipe_handles: pipe_handles ref count = %lu for pipe %s\n", + (unsigned long)p->pipe_handles->pipe_ref_count, pipe_name )); return True; } diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 55def97673..57e45d477f 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -541,7 +541,7 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p) void free_pipe_context(pipes_struct *p) { if (p->mem_ctx) { - DEBUG(3,("free_pipe_context: destroying talloc pool of size %u\n", talloc_pool_size(p->mem_ctx) )); + DEBUG(3,("free_pipe_context: destroying talloc pool of size %lu\n", (unsigned long)talloc_pool_size(p->mem_ctx) )); talloc_destroy_pool(p->mem_ctx); } else { p->mem_ctx = talloc_init("pipe %s %p", p->name, p); diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 6cf7014846..84339c3a6f 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -707,8 +707,8 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) DO_PROFILE_INC(writecache_allocated_write_caches); allocated_write_caches++; - DEBUG(10,("setup_write_cache: File %s allocated write cache size %u\n", - fsp->fsp_name, wcp->alloc_size )); + DEBUG(10,("setup_write_cache: File %s allocated write cache size %lu\n", + fsp->fsp_name, (unsigned long)wcp->alloc_size )); return True; } @@ -725,7 +725,7 @@ void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) if (fsp->wcp->data_size != 0) { pstring msg; slprintf(msg, sizeof(msg)-1, "set_filelen_write_cache: size change \ -on file %s with write cache size = %u\n", fsp->fsp_name, fsp->wcp->data_size ); +on file %s with write cache size = %lu\n", fsp->fsp_name, (unsigned long)fsp->wcp->data_size ); smb_panic(msg); } fsp->wcp->file_size = file_size; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index e7d7c20f6b..8158c67a5e 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1957,8 +1957,8 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid))); if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &uid))) { - DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%u]\n", - sid_string_static(&sid),sid_len)); + DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n", + sid_string_static(&sid),(unsigned long)sid_len)); uid = (-1); } @@ -2169,7 +2169,7 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, sid_len = IVAL(pdata,4); if (data_count < 8+sid_len) { - DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8+sid_len)); + DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len))); return ERROR_DOS(ERRDOS,ERRunknownlevel); } @@ -2302,7 +2302,7 @@ static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, sid_len = IVAL(pdata,4); if (data_count < 40+sid_len) { - DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40+sid_len)); + DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len)); return ERROR_DOS(ERRDOS,ERRunknownlevel); } diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c index ac9cf5b8a6..5de9dd56e6 100644 --- a/source3/smbd/oplock_linux.c +++ b/source3/smbd/oplock_linux.c @@ -226,8 +226,8 @@ static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *i { /* Ensure that the msg length is correct. */ if (msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) { - DEBUG(0,("incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, should be %d).\n", - msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN)); + DEBUG(0,("incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, should be %lu).\n", + msg_len, (unsigned long)KERNEL_OPLOCK_BREAK_MSG_LEN)); return False; } diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 95b45fcc99..aa1d25c483 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -460,7 +460,7 @@ static struct pai_val *load_inherited_info(files_struct *fsp) } } while (ret == -1); - DEBUG(10,("load_inherited_info: ret = %d for file %s\n", ret, fsp->fsp_name)); + DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fsp->fsp_name)); if (ret == -1) { /* No attribute or not supported. */ diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 43ffb82bd7..8a90a15d29 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -637,7 +637,7 @@ static void smb_dump(const char *name, int type, char *data, ssize_t len) if (ret != len) DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret )); close(fd); - DEBUG(0,("created %s len %d\n", fname, len)); + DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len)); } } diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c index 76406f208e..d996f5e493 100644 --- a/source3/smbd/statcache.c +++ b/source3/smbd/statcache.c @@ -119,8 +119,8 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat if (original_path_length != translated_path_length) { if (original_path_length < translated_path_length) { - DEBUG(0, ("OOPS - tried to store stat cache entry for weird length paths [%s] %u and [%s] %u)!\n", - original_path, original_path_length, translated_path, translated_path_length)); + DEBUG(0, ("OOPS - tried to store stat cache entry for weird length paths [%s] %lu and [%s] %lu)!\n", + original_path, (unsigned long)original_path_length, translated_path, (unsigned long)translated_path_length)); SAFE_FREE(original_path); SAFE_FREE(translated_path); return; -- cgit From 7d517167f0f3eeff31bc92066cf012c51f81c684 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 5 Nov 2003 19:16:56 +0000 Subject: Minor comment updates ... (This used to be commit d7a0c6da0baf41faf0eb0b71f3576d3c3fbf7c62) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c3abd63818..d645a2fffb 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -361,7 +361,7 @@ void unlock_share_entry(connection_struct *conn, } /******************************************************************* - Lock a hash bucket entry. use a fsp for convenience + Lock a hash bucket entry. Use an fsp for convenience. ******************************************************************/ BOOL lock_share_entry_fsp(files_struct *fsp) @@ -370,7 +370,7 @@ BOOL lock_share_entry_fsp(files_struct *fsp) } /******************************************************************* - Unlock a hash bucket entry. + Unlock a hash bucket entry. Use an fsp for convenience. ******************************************************************/ void unlock_share_entry_fsp(files_struct *fsp) -- cgit From 3d50c8aa2226aea58695b9295556f805d1cf165d Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 5 Nov 2003 23:36:00 +0000 Subject: Better handling of iconv support and etc because gnu libiconv on FreeBSD changed where it puts things :-) (This used to be commit 123a516a6095e3fb6c2ad372b2800a825bbd2a13) --- source3/configure.in | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 0a6005b28f..8ac4541024 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1605,9 +1605,10 @@ for i in $LOOK_DIRS ; do save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS -I$i/include" dnl This is here to handle -withval stuff for --with-libiconv - if test x"$ICONV_PATH_SPEC" = "xyes" ; then +dnl Perhaps we should always add a -L +dnl if test x"$ICONV_PATH_SPEC" = "xyes" ; then LDFLAGS="-L$i/lib" - fi +dnl fi LIBS= export LDFLAGS LIBS CPPFLAGS dnl Try to find iconv(3) @@ -1616,7 +1617,7 @@ dnl Try to find iconv(3) if test "$ICONV_FOUND" = yes; then LIB_ADD_DIR(LDFLAGS, "$i/lib") CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") - LIBS="$save_LIBS" +dnl LIBS="$save_LIBS" ICONV_LOCATION=$i export LDFLAGS LIBS CPPFLAGS dnl Now, check for a working iconv ... we want to do it here because -- cgit From 9144e46889b68fd4136799f10f2b3e5610346976 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 6 Nov 2003 05:37:30 +0000 Subject: Make the recent changes more pretty. (This used to be commit e490efd29a8a6b1fc7087b7dd51bbd41465803c3) --- source3/configure.in | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 8ac4541024..beb9b1d066 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1606,9 +1606,7 @@ for i in $LOOK_DIRS ; do CPPFLAGS="$CPPFLAGS -I$i/include" dnl This is here to handle -withval stuff for --with-libiconv dnl Perhaps we should always add a -L -dnl if test x"$ICONV_PATH_SPEC" = "xyes" ; then - LDFLAGS="-L$i/lib" -dnl fi + LDFLAGS="-L$i/lib" LIBS= export LDFLAGS LIBS CPPFLAGS dnl Try to find iconv(3) @@ -1617,7 +1615,6 @@ dnl Try to find iconv(3) if test "$ICONV_FOUND" = yes; then LIB_ADD_DIR(LDFLAGS, "$i/lib") CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") -dnl LIBS="$save_LIBS" ICONV_LOCATION=$i export LDFLAGS LIBS CPPFLAGS dnl Now, check for a working iconv ... we want to do it here because -- cgit From 662adfa105967732982a89aa5a0718994a95bc6b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 6 Nov 2003 05:46:23 +0000 Subject: bug 624; make sure to set the GUEST SID rather than using the PDB_DEFAULT flag (This used to be commit 7a60693a47823c2a174886ad44e7af102440ba4d) --- source3/passdb/pdb_guest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/pdb_guest.c b/source3/passdb/pdb_guest.c index 3cd6efb38a..e2b38b1e76 100644 --- a/source3/passdb/pdb_guest.c +++ b/source3/passdb/pdb_guest.c @@ -60,7 +60,7 @@ static NTSTATUS guestsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT * if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT)) return NT_STATUS_UNSUCCESSFUL; - if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) + if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST, PDB_SET)) return NT_STATUS_UNSUCCESSFUL; if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) -- cgit From bf6f61a3fc2e2281dc823fa511df41386bab61ef Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 6 Nov 2003 17:24:24 +0000 Subject: patch from MORIYAMA Masayuki to save LDFLAGS during iconv detection; bug 570 (This used to be commit 2277c6e06c2e5b3ace4b231ff8af03d2d29fac36) --- source3/configure.in | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/configure.in b/source3/configure.in index beb9b1d066..feac7da673 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1613,6 +1613,7 @@ dnl Try to find iconv(3) jm_ICONV($i) if test "$ICONV_FOUND" = yes; then + LDFLAGS=$save_LDFLAG LIB_ADD_DIR(LDFLAGS, "$i/lib") CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") ICONV_LOCATION=$i -- cgit From 25d64aa855c23277cd4cb6cce4a52fa9a591307b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 6 Nov 2003 17:31:43 +0000 Subject: run krb5 logins through the username map if the winbindd lookup fails; bug 698 (This used to be commit f7798571178d18aae9c0be5f437838222bfc25b9) --- source3/auth/auth_util.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 71634f08ed..dd0c0b02dd 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -952,14 +952,16 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, } /**************************************************************************** - Wrapper to allow the getpwnam() call to styrip the domain name and - try again in case a local UNIX user is already there. + Wrapper to allow the getpwnam() call to strip the domain name and + try again in case a local UNIX user is already there. Also run through + the username if we fallback to the username only. ****************************************************************************/ struct passwd *smb_getpwnam( char *domuser ) { struct passwd *pw; char *p; + fstring mapped_username; pw = Get_Pwnam( domuser ); if ( pw ) @@ -969,8 +971,11 @@ struct passwd *smb_getpwnam( char *domuser ) p = strchr( domuser, *lp_winbind_separator() ); - if ( p ) - return Get_Pwnam(p+1); + if ( p ) { + fstrcpy( mapped_username, p ); + map_username( mapped_username ); + return Get_Pwnam(mapped_username); + } return NULL; } -- cgit From 949a05bcb7dcb4f557f35f5ffea815a1665a6a3e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 6 Nov 2003 17:39:01 +0000 Subject: merge's tpot build fix from 3.0 (This used to be commit ac9f9f9ea83b0419d3f1f95b57ff3ead625d7576) --- source3/configure.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index feac7da673..269fdf97ed 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1605,8 +1605,9 @@ for i in $LOOK_DIRS ; do save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS -I$i/include" dnl This is here to handle -withval stuff for --with-libiconv -dnl Perhaps we should always add a -L - LDFLAGS="-L$i/lib" + if test x"$ICONV_PATH_SPEC" = "xyes" ; then + LDFLAGS="-L$i/lib" + fi LIBS= export LDFLAGS LIBS CPPFLAGS dnl Try to find iconv(3) @@ -1616,6 +1617,7 @@ dnl Try to find iconv(3) LDFLAGS=$save_LDFLAG LIB_ADD_DIR(LDFLAGS, "$i/lib") CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") + LIBS="$save_LIBS" ICONV_LOCATION=$i export LDFLAGS LIBS CPPFLAGS dnl Now, check for a working iconv ... we want to do it here because -- cgit From 6a594ea65e9a6a07a64b68f2d987795eba27e324 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Nov 2003 22:07:10 +0000 Subject: Fix bug #471. (const needed in lp_set_name_resolve_order). Jeremy. (This used to be commit 5d52e6b3016960cc3be33d3cd15725cce5fd0580) --- source3/param/loadparm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index bedb57670d..37644c738f 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4244,9 +4244,9 @@ int lp_minor_announce_version(void) Set the global name resolution order (used in smbclient). ************************************************************/ -void lp_set_name_resolve_order(char *new_order) +void lp_set_name_resolve_order(const char *new_order) { - Globals.szNameResolveOrder = new_order; + string_set(&Globals.szNameResolveOrder, new_order); } const char *lp_printername(int snum) -- cgit From 99cbab5c3b2fa9af822415a24832892e869f1d3e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 7 Nov 2003 09:04:57 +0000 Subject: From 3_0: Simple rename of get_socket_addr to get_peer_addr and get_socket_name to get_peer_name. This is to get closer to the getsockname/getpeername system functions. Next step will be the %i macro for the local IP address. I still want to play %L-games in times of port 445. Volker (This used to be commit 99311b437be050fd9ee656cd184f299993d20bfb) --- source3/lib/access.c | 14 +++++++------- source3/lib/util_sock.c | 12 ++++++------ source3/smbd/server.c | 2 +- source3/web/cgi.c | 4 ++-- source3/wrepld/process.c | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/source3/lib/access.c b/source3/lib/access.c index 62414726fb..a642a92d71 100644 --- a/source3/lib/access.c +++ b/source3/lib/access.c @@ -311,21 +311,21 @@ BOOL check_access(int sock, const char **allow_list, const char **deny_list) if (only_ipaddrs_in_list(allow_list) && only_ipaddrs_in_list(deny_list)) { only_ip = True; DEBUG (3, ("check_access: no hostnames in host allow/deny list.\n")); - ret = allow_access(deny_list,allow_list, "", get_socket_addr(sock)); + ret = allow_access(deny_list,allow_list, "", get_peer_addr(sock)); } else { DEBUG (3, ("check_access: hostnames in host allow/deny list.\n")); - ret = allow_access(deny_list,allow_list, get_socket_name(sock,True), - get_socket_addr(sock)); + ret = allow_access(deny_list,allow_list, get_peer_name(sock,True), + get_peer_addr(sock)); } if (ret) { DEBUG(2,("Allowed connection from %s (%s)\n", - only_ip ? "" : get_socket_name(sock,True), - get_socket_addr(sock))); + only_ip ? "" : get_peer_name(sock,True), + get_peer_addr(sock))); } else { DEBUG(0,("Denied connection from %s (%s)\n", - only_ip ? "" : get_socket_name(sock,True), - get_socket_addr(sock))); + only_ip ? "" : get_peer_name(sock,True), + get_peer_addr(sock))); } } diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b59d7aa7eb..bdd167b04d 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -794,12 +794,12 @@ void client_setfd(int fd) char *client_name(void) { - return get_socket_name(client_fd,False); + return get_peer_name(client_fd,False); } char *client_addr(void) { - return get_socket_addr(client_fd); + return get_peer_addr(client_fd); } struct in_addr *client_inaddr(struct sockaddr *sa) @@ -866,7 +866,7 @@ static BOOL matchname(char *remotehost,struct in_addr addr) Return the DNS name of the remote end of a socket. ******************************************************************/ -char *get_socket_name(int fd, BOOL force_lookup) +char *get_peer_name(int fd, BOOL force_lookup) { static pstring name_buf; static fstring addr_buf; @@ -879,10 +879,10 @@ char *get_socket_name(int fd, BOOL force_lookup) with dns. To avoid the delay we avoid the lookup if possible */ if (!lp_hostname_lookups() && (force_lookup == False)) { - return get_socket_addr(fd); + return get_peer_addr(fd); } - p = get_socket_addr(fd); + p = get_peer_addr(fd); /* it might be the same as the last one - save some DNS work */ if (strcmp(p, addr_buf) == 0) return name_buf; @@ -918,7 +918,7 @@ char *get_socket_name(int fd, BOOL force_lookup) Return the IP addr of the remote end of a socket as a string. ******************************************************************/ -char *get_socket_addr(int fd) +char *get_peer_addr(int fd) { struct sockaddr sa; struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index af39bcb757..89d6f92e98 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -398,7 +398,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ /* this is needed so that we get decent entries in smbstatus for port 445 connects */ - set_remote_machine_name(get_socket_addr(smbd_server_fd()), False); + set_remote_machine_name(get_peer_addr(smbd_server_fd()), False); /* Reset global variables in util.c so that client substitutions will be diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 6778e59656..49a8fa92de 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -578,7 +578,7 @@ return the hostname of the client char *cgi_remote_host(void) { if (inetd_server) { - return get_socket_name(1,False); + return get_peer_name(1,False); } return getenv("REMOTE_HOST"); } @@ -589,7 +589,7 @@ return the hostname of the client char *cgi_remote_addr(void) { if (inetd_server) { - return get_socket_addr(1); + return get_peer_addr(1); } return getenv("REMOTE_ADDR"); } diff --git a/source3/wrepld/process.c b/source3/wrepld/process.c index 1f96dc996c..0e9a9b3461 100644 --- a/source3/wrepld/process.c +++ b/source3/wrepld/process.c @@ -342,7 +342,7 @@ static void receive_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET * return; } - fstrcpy(peer,get_socket_addr(q->fd)); + fstrcpy(peer,get_peer_addr(q->fd)); addr=*interpret_addr2(peer); get_our_last_id(&global_wins_table[0][0]); @@ -842,7 +842,7 @@ void construct_reply(struct wins_packet_struct *p) fstring peer; struct in_addr addr; int i; - fstrcpy(peer,get_socket_addr(p->fd)); + fstrcpy(peer,get_peer_addr(p->fd)); addr=*interpret_addr2(peer); for (i=1; i Date: Fri, 7 Nov 2003 10:12:43 +0000 Subject: From 3_0: Implement %i-Macro for the locally used IP address. With this you can again have virtual hosts with different configurations on a single smbd even on port 445. Volker (This used to be commit 3a5130f231a0fd6f7490d3b028361ff0458bfae1) --- source3/lib/substitute.c | 3 +++ source3/lib/util_sock.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index 923afd989f..ee342964d0 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -363,6 +363,9 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len) case 'I' : string_sub(p,"%I", client_addr(),l); break; + case 'i' : + string_sub(p,"%i", client_socket_addr(),l); + break; case 'L' : if (local_machine_name && *local_machine_name) string_sub(p,"%L", local_machine_name,l); diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index bdd167b04d..1d62da53c5 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -802,6 +802,11 @@ char *client_addr(void) return get_peer_addr(client_fd); } +char *client_socket_addr(void) +{ + return get_socket_addr(client_fd); +} + struct in_addr *client_inaddr(struct sockaddr *sa) { struct sockaddr_in *sockin = (struct sockaddr_in *) (sa); @@ -941,6 +946,29 @@ char *get_peer_addr(int fd) return addr_buf; } +char *get_socket_addr(int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + int length = sizeof(sa); + static fstring addr_buf; + + fstrcpy(addr_buf,"0.0.0.0"); + + if (fd == -1) { + return addr_buf; + } + + if (getsockname(fd, &sa, &length) < 0) { + DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + return addr_buf; + } + + fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); + + return addr_buf; +} + /******************************************************************* Create protected unix domain socket. -- cgit From 178a4635245c2c433b9a510282ad5c49a2ffe804 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 Nov 2003 14:32:55 +0000 Subject: don't allow setting of the guest account (This used to be commit 1e461f06ec492dc3f139165932c3518a6dd416f9) --- source3/passdb/pdb_guest.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/passdb/pdb_guest.c b/source3/passdb/pdb_guest.c index e2b38b1e76..7e9c2a9e1b 100644 --- a/source3/passdb/pdb_guest.c +++ b/source3/passdb/pdb_guest.c @@ -110,7 +110,15 @@ static NTSTATUS guestsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT static NTSTATUS guestsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd) { +#if 0 /* JERRY */ return methods->parent->pdb_add_sam_account(methods->parent, newpwd); +#else + /* I don't think we should allow any modification of + the guest account as SID will could messed up with + the smbpasswd backend --jerry */ + + return NT_STATUS_NOT_IMPLEMENTED; +#endif } NTSTATUS pdb_init_guestsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -- cgit From e9bd28d0a7b0fd667e52683013404dc4b1e03673 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 Nov 2003 14:41:08 +0000 Subject: fix for bug 680 (heads up). This gist is to map the UNIX entity foo to DOMAIN\foo instead of SERVER\foo on members of a Samba domain when all UNIX accounts are shared via NIS, et. al. * allow winbindd to match local accounts to domain SID when 'winbind trusted domains only = yes' * remove code in idmap_ldap that searches the user suffix and group suffix. It's not needed and provides inconsistent functionality from the tdb backend. This has been tested. I'm still waiting on some more feedback but This needs to be in 3.0.1pre2 for widespread use. (This used to be commit cac4723e206bd001882011c9e12327064d032268) --- source3/nsswitch/winbindd_sid.c | 240 +++++++++++++++++--- source3/passdb/lookup_sid.c | 22 +- source3/sam/idmap_ldap.c | 484 +++++++++++----------------------------- 3 files changed, 361 insertions(+), 385 deletions(-) diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index ac1ee11555..0faeec5636 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -130,16 +130,75 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid, state->request.data.sid)); - /* Split sid into domain sid and user rid */ if (!string_to_sid(&sid, state->request.data.sid)) { DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid)); return WINBINDD_ERROR; } + /* This gets a little tricky. If we assume that usernames are syncd between + /etc/passwd and the windows domain (such as a member of a Samba domain), + the we need to get the uid from the OS and not alocate one ourselves */ + + if ( lp_winbind_trusted_domains_only() ) { + struct winbindd_domain *domain = NULL; + DOM_SID sid2; + uint32 rid; + + domain = find_domain_from_name( lp_workgroup() ); + if ( !domain ) { + DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n")); + return WINBINDD_ERROR; + } + + sid_copy( &sid2, &sid ); + sid_split_rid( &sid2, &rid ); + + if ( sid_equal( &sid2, &domain->sid ) ) { + + fstring domain_name; + fstring user; + enum SID_NAME_USE type; + struct passwd *pw = NULL; + unid_t id; + + /* ok...here's we know that we are dealing with our + own domain (the one to which we are joined). And + we know that there must be a UNIX account for this user. + So we lookup the sid and the call getpwnam().*/ + + + /* But first check and see if we don't already have a mapping */ + + flags = ID_QUERY_ONLY; + if ( NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) ) + return WINBINDD_OK; + + /* now fall back to the hard way */ + + if ( !winbindd_lookup_name_by_sid(&sid, domain_name, user, &type) ) + return WINBINDD_ERROR; + + if ( !(pw = getpwnam(user)) ) { + DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is " + "set but this user [%s] doesn't exist!\n", user)); + return WINBINDD_ERROR; + } + + state->response.data.uid = pw->pw_uid; + + id.uid = pw->pw_uid; + idmap_set_mapping( &sid, id, ID_USERID ); + + return WINBINDD_OK; + } + + } + if ( state->request.flags & WBFLAG_QUERY_ONLY ) flags = ID_QUERY_ONLY; /* Find uid for this sid and return it */ + if ( !NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) ) { DEBUG(1, ("Could not get uid for sid %s\n", state->request.data.sid)); return WINBINDD_ERROR; @@ -167,6 +226,64 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) return WINBINDD_ERROR; } + /* This gets a little tricky. If we assume that usernames are syncd between + /etc/passwd and the windows domain (such as a member of a Samba domain), + the we need to get the uid from the OS and not alocate one ourselves */ + + if ( lp_winbind_trusted_domains_only() ) { + struct winbindd_domain *domain = NULL; + DOM_SID sid2; + uint32 rid; + unid_t id; + + domain = find_domain_from_name( lp_workgroup() ); + if ( !domain ) { + DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n")); + return WINBINDD_ERROR; + } + + sid_copy( &sid2, &sid ); + sid_split_rid( &sid2, &rid ); + + if ( sid_equal( &sid2, &domain->sid ) ) { + + fstring domain_name; + fstring group; + enum SID_NAME_USE type; + struct group *grp = NULL; + + /* ok...here's we know that we are dealing with our + own domain (the one to which we are joined). And + we know that there must be a UNIX account for this group. + So we lookup the sid and the call getpwnam().*/ + + /* But first check and see if we don't already have a mapping */ + + flags = ID_QUERY_ONLY; + if ( NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) ) + return WINBINDD_OK; + + /* now fall back to the hard way */ + + if ( !winbindd_lookup_name_by_sid(&sid, domain_name, group, &type) ) + return WINBINDD_ERROR; + + if ( !(grp = getgrnam(group)) ) { + DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is " + "set but this group [%s] doesn't exist!\n", group)); + return WINBINDD_ERROR; + } + + state->response.data.gid = grp->gr_gid; + + id.gid = grp->gr_gid; + idmap_set_mapping( &sid, id, ID_GROUPID ); + + return WINBINDD_OK; + } + + } + if ( state->request.flags & WBFLAG_QUERY_ONLY ) flags = ID_QUERY_ONLY; @@ -185,28 +302,65 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) { DOM_SID sid; -#if 0 /* JERRY */ - /* we cannot do this check this anymore since a domain member of - a Samba domain may share unix accounts via NIS or LDAP. In this - case the uid/gid will be out of winbindd's range but still might - be resolved to a SID via an ldap idmap backend */ - - if ((state->request.data.uid < server_state.uid_low ) || - (state->request.data.uid > server_state.uid_high)) { - return WINBINDD_ERROR; - } -#endif - DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid, (unsigned long)state->request.data.uid)); + if ( (state->request.data.uid < server_state.uid_low ) + || (state->request.data.uid > server_state.uid_high) ) + { + struct passwd *pw = NULL; + enum SID_NAME_USE type; + unid_t id; + struct winbindd_domain *domain; + + /* SPECIAL CASE FOR MEMBERS OF SAMBA DOMAINS */ + + /* if we don't trust /etc/password then when can't know + anything about this uid */ + + if ( !lp_winbind_trusted_domains_only() ) + return WINBINDD_ERROR; + + + /* look for an idmap entry first */ + + if ( NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid)) ) + goto done; + + /* if users exist in /etc/passwd, we should try to + use that uid. Get the username and the lookup the SID */ + + if ( !(pw = getpwuid(state->request.data.uid)) ) + return WINBINDD_ERROR; + + if ( !(domain = find_domain_from_name(lp_workgroup())) ) { + DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n")); + return WINBINDD_ERROR; + } + + if ( !winbindd_lookup_sid_by_name(domain, pw->pw_name, &sid, &type) ) + return WINBINDD_ERROR; + + if ( type != SID_NAME_USER ) + return WINBINDD_ERROR; + + /* don't fail if we can't store it */ + + id.uid = pw->pw_uid; + idmap_set_mapping( &sid, id, ID_USERID ); + + goto done; + } + /* Lookup rid for this uid */ + if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid))) { DEBUG(1, ("Could not convert uid %lu to rid\n", (unsigned long)state->request.data.uid)); return WINBINDD_ERROR; } +done: sid_to_string(state->response.data.sid.sid, &sid); state->response.data.sid.type = SID_NAME_USER; @@ -219,28 +373,64 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) { DOM_SID sid; -#if 0 /* JERRY */ - /* we cannot do this check this anymore since a domain member of - a Samba domain may share unix accounts via NIS or LDAP. In this - case the uid/gid will be out of winbindd's range but still might - be resolved to a SID via an ldap idmap backend */ - - if ((state->request.data.gid < server_state.gid_low) || - (state->request.data.gid > server_state.gid_high)) { - return WINBINDD_ERROR; - } -#endif - DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid, (unsigned long)state->request.data.gid)); + + if ( (state->request.data.gid < server_state.gid_low) + || (state->request.data.gid > server_state.gid_high) ) + { + struct group *grp = NULL; + enum SID_NAME_USE type; + unid_t id; + struct winbindd_domain *domain; + + /* SPECIAL CASE FOR MEMBERS OF SAMBA DOMAINS */ + + /* if we don't trust /etc/group then when can't know + anything about this gid */ + + if ( !lp_winbind_trusted_domains_only() ) + return WINBINDD_ERROR; + + /* look for an idmap entry first */ + + if ( NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid)) ) + goto done; + + /* if users exist in /etc/group, we should try to + use that gid. Get the username and the lookup the SID */ + + if ( !(grp = getgrgid(state->request.data.gid)) ) + return WINBINDD_ERROR; + + if ( !(domain = find_domain_from_name(lp_workgroup())) ) { + DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n")); + return WINBINDD_ERROR; + } + + if ( !winbindd_lookup_sid_by_name(domain, grp->gr_name, &sid, &type) ) + return WINBINDD_ERROR; + + if ( type!=SID_NAME_DOM_GRP && type!=SID_NAME_ALIAS ) + return WINBINDD_ERROR; + + /* don't fail if we can't store it */ + + id.gid = grp->gr_gid; + idmap_set_mapping( &sid, id, ID_GROUPID ); + + goto done; + } /* Lookup sid for this uid */ + if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid))) { DEBUG(1, ("Could not convert gid %lu to sid\n", (unsigned long)state->request.data.gid)); return WINBINDD_ERROR; } +done: /* Construct sid and return it */ sid_to_string(state->response.data.sid.sid, &sid); state->response.data.sid.type = SID_NAME_DOM_GRP; diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index f84ff28db9..425c9b87f1 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -299,15 +299,20 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid) NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid) { - uid_t low, high; fstring sid; + uid_t low, high; ZERO_STRUCTP(psid); if (fetch_sid_from_uid_cache(psid, uid)) return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); - if (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) { + /* DC's never use winbindd to resolve users outside the + defined idmap range */ + + if ( lp_server_role()==ROLE_DOMAIN_MEMBER + || (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) ) + { if (winbind_uid_to_sid(psid, uid)) { DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", @@ -336,15 +341,20 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid) NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid) { - gid_t low, high; fstring sid; + gid_t low, high; ZERO_STRUCTP(psid); if (fetch_sid_from_gid_cache(psid, gid)) return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); - if (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) { + /* DC's never use winbindd to resolve groups outside the + defined idmap range */ + + if ( lp_server_role()==ROLE_DOMAIN_MEMBER + || (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) ) + { if (winbind_gid_to_sid(psid, gid)) { DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", @@ -458,7 +468,9 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid) /* winbindd knows it; Ensure this is a group sid */ - if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { + if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) + && (name_type != SID_NAME_WKN_GRP)) + { DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n", (unsigned int)name_type )); diff --git a/source3/sam/idmap_ldap.c b/source3/sam/idmap_ldap.c index 72fcb47b03..2a94de755a 100644 --- a/source3/sam/idmap_ldap.c +++ b/source3/sam/idmap_ldap.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. idmap LDAP backend @@ -7,17 +7,17 @@ Copyright (C) Jim McDonough 2003 Copyright (C) Simo Sorce 2003 Copyright (C) Gerald Carter 2003 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -34,25 +34,84 @@ #include "smbldap.h" -#define IDMAP_GROUP_SUFFIX "ou=idmap group" -#define IDMAP_USER_SUFFIX "ou=idmap people" - - struct ldap_idmap_state { struct smbldap_state *smbldap_state; TALLOC_CTX *mem_ctx; }; -#define LDAP_MAX_ALLOC_ID 128 /* number tries while allocating - new id */ - static struct ldap_idmap_state ldap_state; -static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type); -static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id, int id_type, - const char *ldap_dn, LDAPMessage *entry); -static NTSTATUS ldap_idmap_close(void); +/* number tries while allocating new id */ +#define LDAP_MAX_ALLOC_ID 128 + + +/*********************************************************************** + This function cannot be called to modify a mapping, only set a new one +***********************************************************************/ +static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) +{ + pstring dn; + pstring id_str; + fstring type; + LDAPMod **mods = NULL; + int rc = -1; + int ldap_op; + fstring sid_string; + LDAPMessage *entry = NULL; + + sid_to_string( sid_string, sid ); + + ldap_op = LDAP_MOD_ADD; + pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID), + sid_string, lp_ldap_idmap_suffix()); + + if ( id_type & ID_USERID ) + fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ) ); + else + fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) ); + + pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid : + (unsigned long)id.gid)); + + smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY ); + + smbldap_make_mod( ldap_state.smbldap_state->ldap_struct, + entry, &mods, type, id_str ); + + smbldap_make_mod( ldap_state.smbldap_state->ldap_struct, + entry, &mods, + get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), + sid_string ); + + /* There may well be nothing at all to do */ + + if (mods) { + smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY ); + rc = smbldap_add(ldap_state.smbldap_state, dn, mods); + ldap_mods_free( mods, True ); + } else { + rc = LDAP_SUCCESS; + } + + if (rc != LDAP_SUCCESS) { + char *ld_error = NULL; + ldap_get_option(ldap_state.smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, + &ld_error); + DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n", + (ldap_op == LDAP_MOD_ADD) ? "add" : "replace", + sid_string, (unsigned long)((id_type & ID_USERID) ? id.uid : id.gid), type)); + DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", + ld_error ? ld_error : "(NULL)", ldap_err2string (rc))); + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n", + sid_string, ((id_type & ID_USERID) ? (unsigned long)id.uid : + (unsigned long)id.gid), type)); + + return NT_STATUS_OK; +} /********************************************************************** Even if the sambaDomain attribute in LDAP tells us that this RID is @@ -77,7 +136,7 @@ static BOOL sid_in_use(struct ldap_idmap_state *state, if (rc != LDAP_SUCCESS) { char *ld_error = NULL; ldap_get_option(state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); - DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n", + DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n", sid_string, ld_error)); SAFE_FREE(ld_error); @@ -142,7 +201,7 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, } /* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and - algorithmic_rid_base. The other two are to avoid stomping on the + algorithmic_rid_base. The other two are to avoid stomping on the different sets of algorithmic RIDs */ if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry, @@ -337,7 +396,7 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) pstr_sprintf(filter, "(objectClass=%s)", LDAP_OBJ_IDPOOL); attr_list = get_attr_list( idpool_attr_list ); - + rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(), LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result); @@ -421,86 +480,45 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) { LDAPMessage *result = NULL; LDAPMessage *entry = NULL; - fstring id_str; pstring sid_str; pstring filter; pstring suffix; const char *type; - const char *obj_class; int rc; int count; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; char **attr_list; - /* first we try for a samba user or group mapping */ - - if ( id_type & ID_USERID ) { + if ( id_type & ID_USERID ) type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); - obj_class = LDAP_OBJ_SAMBASAMACCOUNT; - fstr_sprintf(id_str, "%lu", (unsigned long)id.uid ); - pstrcpy( suffix, lp_ldap_suffix()); - } - else { + else type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); - obj_class = LDAP_OBJ_GROUPMAP; - fstr_sprintf(id_str, "%lu", (unsigned long)id.gid ); - pstrcpy( suffix, lp_ldap_group_suffix() ); - } + + pstrcpy( suffix, lp_ldap_idmap_suffix() ); + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))", + LDAP_OBJ_IDMAP_ENTRY, type, + ((id_type & ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid)); + DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter )); attr_list = get_attr_list( sidmap_attr_list ); - pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))", - LDAP_OBJ_IDMAP_ENTRY, obj_class, type, id_str); - rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, - filter, attr_list, 0, &result); - + filter, attr_list, 0, &result); + if (rc != LDAP_SUCCESS) { DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n", ldap_err2string(rc) )); goto out; } - - count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); - - if (count > 1) { - DEBUG(0,("ldap_get_sid_from_id: mapping returned [%d] entries!\n", - count)); - goto out; - } - - /* fall back to looking up an idmap entry if we didn't find and - actual user or group */ - - if (count == 0) { - ldap_msgfree(result); - result = NULL; - - pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))", - LDAP_OBJ_IDMAP_ENTRY, type, - ((id_type & ID_USERID) ? (unsigned long)id.uid : - (unsigned long)id.gid)); - - pstrcpy( suffix, lp_ldap_idmap_suffix() ); - - rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, - filter, attr_list, 0, &result); - - if (rc != LDAP_SUCCESS) { - DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n", - ldap_err2string(rc) )); - goto out; - } - count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); + count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); - if (count != 1) { - DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n", - type, ((id_type & ID_USERID) ? (unsigned long)id.uid : - (unsigned long)id.gid))); - goto out; - } + if (count != 1) { + DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n", + type, ((id_type & ID_USERID) ? (unsigned long)id.uid : + (unsigned long)id.gid))); + goto out; } entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); @@ -508,7 +526,7 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) if ( !smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID, sid_str) ) goto out; - if (!string_to_sid(sid, sid_str)) + if (!string_to_sid(sid, sid_str)) goto out; ret = NT_STATUS_OK; @@ -545,29 +563,14 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str, (*id_type & ID_GROUPID ? "group" : "user") )); - /* ahhh.... ok. We have to check users and groups in places other - than idmap (hint: we're a domain member of a Samba domain) */ - - if ( *id_type & ID_GROUPID ) { - + suffix = lp_ldap_idmap_suffix(); + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", + LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str); + + if ( *id_type & ID_GROUPID ) type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ); - suffix = lp_ldap_group_suffix(); - pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))", - LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY, - get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ), - sid_str); - - } - else { - + else type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ); - suffix = lp_ldap_suffix(); - pstr_sprintf(filter, "(&(|(&(objectClass=%s)(objectClass=%s))(objectClass=%s))(%s=%s))", - LDAP_OBJ_SAMBASAMACCOUNT, LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_IDMAP_ENTRY, - get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ), - sid_str); - - } DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter)); @@ -575,84 +578,55 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si attr_list = get_attr_list( sidmap_attr_list ); rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, - filter, attr_list, 0, &result); - - if ( rc != LDAP_SUCCESS ) { - DEBUG(3,("ldap_get_id_from_sid: Failure looking up group mapping (%s)\n", + filter, attr_list, 0, &result); + + if (rc != LDAP_SUCCESS) { + DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n", ldap_err2string(rc) )); goto out; } + + /* check for the number of entries returned */ count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); - + if ( count > 1 ) { - DEBUG(3,("ldap_get_id_from_sid: search \"%s\" returned [%d] entries. Bailing...\n", + DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n", filter, count)); goto out; } + + /* try to allocate a new id if we still haven't found one */ - /* see if we need to do a search here */ - - if ( count == 0 ) { - - if ( result ) { - ldap_msgfree(result); - result = NULL; - } - - /* look in idmap suffix */ - - suffix = lp_ldap_idmap_suffix(); - pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", - LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str); + if ( !count ) { + int i; - rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, - filter, attr_list, 0, &result); - - if (rc != LDAP_SUCCESS) { - DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n", - ldap_err2string(rc) )); + if (*id_type & ID_QUERY_ONLY) { + DEBUG(5,("ldap_get_id_from_sid: No matching entry found and QUERY_ONLY flag set\n")); goto out; } - - /* check for the number of entries returned */ - count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); - - if ( count > 1 ) { - DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n", - filter, count)); - goto out; - } - - - /* try to allocate a new id if we still haven't found one */ - - if ( (count==0) && !(*id_type & ID_QUERY_ONLY) ) { - int i; - - DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n")); + DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n")); - for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) { - ret = ldap_allocate_id(id, *id_type); - if ( NT_STATUS_IS_OK(ret) ) - break; - } + for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) { + ret = ldap_allocate_id(id, *id_type); + if ( NT_STATUS_IS_OK(ret) ) + break; + } - if ( !NT_STATUS_IS_OK(ret) ) { - DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n")); - goto out; - } + if ( !NT_STATUS_IS_OK(ret) ) { + DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n")); + goto out; + } - DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n", - (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid )); + DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n", + (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid )); - ret = ldap_set_mapping(sid, *id, *id_type); + ret = ldap_set_mapping(sid, *id, *id_type); - /* all done */ + /* all done */ - goto out; - } + goto out; } DEBUG(10,("ldap_get_id_from_sid: success\n")); @@ -684,206 +658,6 @@ out: return ret; } -/*********************************************************************** - This function cannot be called to modify a mapping, only set a new one - - This takes a possible pointer to the existing entry for the UID or SID - involved. -***********************************************************************/ - -static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id, - int id_type, const char *ldap_dn, - LDAPMessage *entry) -{ - pstring dn; - pstring id_str; - fstring type; - LDAPMod **mods = NULL; - int rc = -1; - int ldap_op; - fstring sid_string; - char **values = NULL; - int i; - - sid_to_string( sid_string, sid ); - - if (ldap_dn) { - DEBUG(10, ("Adding new IDMAP mapping on DN: %s", ldap_dn)); - ldap_op = LDAP_MOD_REPLACE; - pstrcpy( dn, ldap_dn ); - } else { - ldap_op = LDAP_MOD_ADD; - pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID), - sid_string, lp_ldap_idmap_suffix()); - } - - if ( id_type & ID_USERID ) - fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ) ); - else - fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) ); - - pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid : - (unsigned long)id.gid)); - - if (entry) - values = ldap_get_values(ldap_state.smbldap_state->ldap_struct, entry, "objectClass"); - - if (values) { - BOOL found_idmap = False; - for (i=0; values[i]; i++) { - if (StrCaseCmp(values[i], LDAP_OBJ_IDMAP_ENTRY) == 0) { - found_idmap = True; - break; - } - } - if (!found_idmap) - smbldap_set_mod( &mods, LDAP_MOD_ADD, - "objectClass", LDAP_OBJ_IDMAP_ENTRY ); - } else { - smbldap_set_mod( &mods, LDAP_MOD_ADD, - "objectClass", LDAP_OBJ_IDMAP_ENTRY ); - } - - smbldap_make_mod( ldap_state.smbldap_state->ldap_struct, - entry, &mods, type, id_str ); - - smbldap_make_mod( ldap_state.smbldap_state->ldap_struct, - entry, &mods, - get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), - sid_string ); - - /* There may well be nothing at all to do */ - if (mods) { - switch(ldap_op) - { - case LDAP_MOD_ADD: - smbldap_set_mod( &mods, LDAP_MOD_ADD, - "objectClass", LDAP_OBJ_SID_ENTRY ); - rc = smbldap_add(ldap_state.smbldap_state, dn, mods); - break; - case LDAP_MOD_REPLACE: - rc = smbldap_modify(ldap_state.smbldap_state, dn, mods); - break; - } - - ldap_mods_free( mods, True ); - } else { - rc = LDAP_SUCCESS; - } - - if (rc != LDAP_SUCCESS) { - char *ld_error = NULL; - ldap_get_option(ldap_state.smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, - &ld_error); - DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n", - (ldap_op == LDAP_MOD_ADD) ? "add" : "replace", - sid_string, (unsigned long)((id_type & ID_USERID) ? id.uid : id.gid), type)); - DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", ld_error ? ld_error : "(NULL)", ldap_err2string (rc))); - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n", - sid_string, ((id_type & ID_USERID) ? (unsigned long)id.uid : - (unsigned long)id.gid), type)); - - return NT_STATUS_OK; -} - -/*********************************************************************** - This function cannot be called to modify a mapping, only set a new one -***********************************************************************/ - -static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - char *dn = NULL; - LDAPMessage *result = NULL; - LDAPMessage *entry = NULL; - const char *type; - const char *obj_class; - const char *posix_obj_class; - const char *suffix; - fstring sid_str; - fstring id_str; - pstring filter; - char **attr_list; - int rc; - int count; - - /* try for a samba user or group mapping (looking for an entry with a SID) */ - if ( id_type & ID_USERID ) { - obj_class = LDAP_OBJ_SAMBASAMACCOUNT; - suffix = lp_ldap_suffix(); - type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); - posix_obj_class = LDAP_OBJ_POSIXACCOUNT; - fstr_sprintf(id_str, "%lu", (unsigned long)id.uid ); - } - else { - obj_class = LDAP_OBJ_GROUPMAP; - suffix = lp_ldap_group_suffix(); - type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); - posix_obj_class = LDAP_OBJ_POSIXGROUP; - fstr_sprintf(id_str, "%lu", (unsigned long)id.gid ); - } - - sid_to_string(sid_str, sid); - pstr_sprintf(filter, - "(|" - "(&(|(objectClass=%s)(|(objectClass=%s)(objectClass=%s)))(%s=%s))" - "(&(objectClass=%s)(%s=%s))" - ")", - /* objectClasses that might contain a SID */ - LDAP_OBJ_SID_ENTRY, LDAP_OBJ_IDMAP_ENTRY, obj_class, - get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ), - sid_str, - - /* objectClasses that might contain a Unix UID/GID */ - posix_obj_class, - /* Unix UID/GID specifier*/ - type, - /* actual ID */ - id_str); - - attr_list = get_attr_list( sidmap_attr_list ); - rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, - filter, attr_list, 0, &result); - free_attr_list( attr_list ); - - if (rc != LDAP_SUCCESS) - goto out; - - count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); - - /* fall back to looking up an idmap entry if we didn't find anything under the idmap - user or group suffix */ - - if (count == 1) { - entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); - - dn = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result); - if (!dn) - goto out; - DEBUG(10, ("Found partial mapping entry at dn=%s, looking for %s\n", dn, type)); - - ret = ldap_set_mapping_internals(sid, id, id_type, dn, entry); - - goto out; - } else if (count > 1) { - DEBUG(0, ("Too many entries trying to find DN to attach ldap \n")); - goto out; - } - - ret = ldap_set_mapping_internals(sid, id, id_type, NULL, NULL); - -out: - if (result) - ldap_msgfree(result); - SAFE_FREE(dn); - - return ret; -} - - /********************************************************************** Verify the sambaUnixIdPool entry in the directiry. **********************************************************************/ -- cgit From a3aa2c9ed44f5967986d340456efd5828bd5f2ff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Nov 2003 18:32:29 +0000 Subject: Handle munged dial string. Patch from Aur?lien Degr?mont with memory leak fixes by me. Jeremy. (This used to be commit daceed37387c517b3f0ab9c173f419215e3d676b) --- source3/rpc_parse/parse_misc.c | 21 +++++++++++++ source3/rpc_parse/parse_samr.c | 19 ++++++++---- source3/rpc_server/srv_samr_nt.c | 37 ++++++++++++++++++++++- source3/rpc_server/srv_samr_util.c | 60 +++++++++++++++++++++++++++++++------- 4 files changed, 121 insertions(+), 16 deletions(-) diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index a075dbd833..b0144c2c89 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -1028,6 +1028,27 @@ void init_unistr2_from_unistr(UNISTR2 *to, const UNISTR *from) return; } +/******************************************************************* + Inits a UNISTR2 structure from a DATA_BLOB. + The length of the data_blob must count the bytes of the buffer. + Copies the blob data. +********************************************************************/ + +void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) +{ + /* Allocs the unistring */ + init_unistr2(str, NULL, UNI_FLAGS_NONE); + + /* Sets the values */ + str->uni_str_len = blob->length / sizeof(uint16); + str->uni_max_len = str->uni_str_len; + str->offset = 0; + str->buffer = (uint16 *) memdup(blob->data, blob->length); + if (!str->buffer) { + smb_panic("init_unistr2_from_datablob: malloc fail\n"); + } +} + /******************************************************************* Reads or writes a UNISTR2 structure. XXXX NOTE: UNISTR2 structures need NOT be null-terminated. diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 939b652a1e..73107f8f61 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -5485,6 +5485,8 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z LOGON_HRS * hrs, uint16 bad_password_count, uint16 logon_count, char newpass[516], uint32 unknown_6) { + DATA_BLOB blob = base64_decode_data_blob(mung_dial); + usr->logon_time = *logon_time; /* all zeros */ usr->logoff_time = *logoff_time; /* all zeros */ usr->kickoff_time = *kickoff_time; /* all zeros */ @@ -5544,9 +5546,11 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z init_unistr2(&usr->uni_unknown_str, unk_str, UNI_FLAGS_NONE); init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str); - init_unistr2(&usr->uni_munged_dial, mung_dial, UNI_FLAGS_NONE); + init_unistr2_from_datablob(&usr->uni_munged_dial, &blob); init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial); + data_blob_free(&blob); + usr->unknown_6 = unknown_6; /* 0x0000 04ec */ usr->padding4 = 0; @@ -5934,6 +5938,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * const char* description = pdb_get_acct_desc(pw); const char* workstations = pdb_get_workstations(pw); const char* munged_dial = pdb_get_munged_dial(pw); + DATA_BLOB blob = base64_decode_data_blob(munged_dial); uint32 user_rid; const DOM_SID *user_sid; @@ -5970,6 +5975,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * user_name, sid_to_string(user_sid_string, user_sid), sid_to_string(domain_sid_string, domain_sid))); + data_blob_free(&blob); return NT_STATUS_UNSUCCESSFUL; } @@ -5983,6 +5989,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * user_name, sid_to_string(group_sid_string, group_sid), sid_to_string(domain_sid_string, domain_sid))); + data_blob_free(&blob); return NT_STATUS_UNSUCCESSFUL; } @@ -6042,8 +6049,9 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * init_unistr2(&usr->uni_unknown_str, NULL, UNI_STR_TERMINATE); init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str); - init_unistr2(&usr->uni_munged_dial, munged_dial, UNI_STR_TERMINATE); + init_unistr2_from_datablob(&usr->uni_munged_dial, &blob); init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial); + data_blob_free(&blob); usr->unknown_6 = pdb_get_unknown_6(pw); usr->padding4 = 0; @@ -6184,10 +6192,11 @@ static BOOL sam_io_user_info21(const char *desc, SAM_USER_INFO_21 * usr, void init_sam_user_info20A(SAM_USER_INFO_20 *usr, SAM_ACCOUNT *pw) { const char *munged_dial = pdb_get_munged_dial(pw); - - init_unistr2(&usr->uni_munged_dial, munged_dial, UNI_STR_TERMINATE); + DATA_BLOB blob = base64_decode_data_blob(munged_dial); + + init_unistr2_from_datablob(&usr->uni_munged_dial, &blob); init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial); - + data_blob_free(&blob); } /******************************************************************* diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 71e5bc7d70..446eff9045 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2788,6 +2788,38 @@ static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass) } +/******************************************************************* + set_user_info_20 + ********************************************************************/ + +static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid) +{ + SAM_ACCOUNT *pwd = NULL; + + if (id20 == NULL) { + DEBUG(5, ("set_user_info_20: NULL id20\n")); + return False; + } + + pdb_init_sam(&pwd); + + if (!pdb_getsampwsid(pwd, sid)) { + pdb_free_sam(&pwd); + return False; + } + + copy_id20_to_sam_passwd(pwd, id20); + + /* write the change out */ + if(!pdb_update_sam_account(pwd)) { + pdb_free_sam(&pwd); + return False; + } + + pdb_free_sam(&pwd); + + return True; +} /******************************************************************* set_user_info_21 ********************************************************************/ @@ -3091,6 +3123,10 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_ if (!set_user_info_21(ctr->info.id21, &sid)) return NT_STATUS_ACCESS_DENIED; break; + case 20: + if (!set_user_info_20(ctr->info.id20, &sid)) + return NT_STATUS_ACCESS_DENIED; + break; case 16: if (!set_user_info_10(ctr->info.id10, &sid)) return NT_STATUS_ACCESS_DENIED; @@ -4537,4 +4573,3 @@ NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R return r_u->status; } - diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index db6649073e..82f93a5b4c 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -31,6 +31,36 @@ (!old_string && new_string) ||\ (old_string && new_string && (strcmp(old_string, new_string) != 0)) +#define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\ + (!(s1) && (s2)) ||\ + ((s1) && (s2) && (strcmp((s1), (s2)) != 0)) + +/************************************************************* + Copies a SAM_USER_INFO_20 to a SAM_ACCOUNT +**************************************************************/ + +void copy_id20_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_20 *from) +{ + const char *old_string; + char *new_string; + DATA_BLOB mung; + + if (from == NULL || to == NULL) + return; + + if (from->hdr_munged_dial.buffer) { + old_string = pdb_get_munged_dial(to); + mung.length = from->hdr_munged_dial.uni_str_len; + mung.data = (uint8 *) from->uni_munged_dial.buffer; + new_string = base64_encode_data_blob(mung); + DEBUG(10,("INFO_20 UNI_MUNGED_DIAL: %s -> %s\n",old_string, new_string)); + if (STRING_CHANGED_NC(old_string,new_string)) + pdb_set_munged_dial(to , new_string, PDB_CHANGED); + + SAFE_FREE(new_string); + } +} + /************************************************************* Copies a SAM_USER_INFO_21 to a SAM_ACCOUNT **************************************************************/ @@ -39,6 +69,7 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) { time_t unix_time, stored_time; const char *old_string, *new_string; + DATA_BLOB mung; if (from == NULL || to == NULL) return; @@ -162,11 +193,16 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) } if (from->hdr_munged_dial.buffer) { + char *newstr; old_string = pdb_get_munged_dial(to); - new_string = unistr2_static(&from->uni_munged_dial); - DEBUG(10,("INFO_21 UNI_MUNGED_DIAL: %s -> %s\n",old_string, new_string)); - if (STRING_CHANGED) - pdb_set_munged_dial(to , new_string, PDB_CHANGED); + mung.length = from->hdr_munged_dial.uni_str_len; + mung.data = (uint8 *) from->uni_munged_dial.buffer; + newstr = base64_encode_data_blob(mung); + DEBUG(10,("INFO_21 UNI_MUNGED_DIAL: %s -> %s\n",old_string, newstr)); + if (STRING_CHANGED_NC(old_string,newstr)) + pdb_set_munged_dial(to , newstr, PDB_CHANGED); + + SAFE_FREE(newstr); } if (from->user_rid == 0) { @@ -250,6 +286,7 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) { time_t unix_time, stored_time; const char *old_string, *new_string; + DATA_BLOB mung; if (from == NULL || to == NULL) return; @@ -373,11 +410,16 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) } if (from->hdr_munged_dial.buffer) { + char *newstr; old_string = pdb_get_munged_dial(to); - new_string = unistr2_static(&from->uni_munged_dial); - DEBUG(10,("INFO_23 UNI_MUNGED_DIAL: %s -> %s\n",old_string, new_string)); - if (STRING_CHANGED) - pdb_set_munged_dial(to , new_string, PDB_CHANGED); + mung.length = from->hdr_munged_dial.uni_str_len; + mung.data = (uint8 *) from->uni_munged_dial.buffer; + newstr = base64_encode_data_blob(mung); + DEBUG(10,("INFO_23 UNI_MUNGED_DIAL: %s -> %s\n",old_string, newstr)); + if (STRING_CHANGED_NC(old_string, newstr)) + pdb_set_munged_dial(to , newstr, PDB_CHANGED); + + SAFE_FREE(newstr); } if (from->user_rid == 0) { @@ -450,5 +492,3 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) DEBUG(10,("INFO_23 PADDING_4: %08X\n",from->padding4)); } - - -- cgit From f9230c937b1304e6864aa020a4e102749ca6f8ae Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 Nov 2003 23:04:52 +0000 Subject: * only install swat html files once * revert the change that prevent the guest account from being added to a passdb backend since it broke the build farm. * apply patch from Alex Deiter to fix the "smbldap_open: cannot access when not root error" messages when looking up group information (bug 281) (This used to be commit 20bd309239199d85accb2b7aac6d4dd73e414f85) --- source3/passdb/pdb_guest.c | 5 ++++- source3/rpc_server/srv_samr_nt.c | 20 +++++++++++++++++--- source3/script/installswat.sh | 26 +++++++++++++------------- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/source3/passdb/pdb_guest.c b/source3/passdb/pdb_guest.c index 7e9c2a9e1b..8c1d4c7b0f 100644 --- a/source3/passdb/pdb_guest.c +++ b/source3/passdb/pdb_guest.c @@ -110,7 +110,10 @@ static NTSTATUS guestsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT static NTSTATUS guestsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd) { -#if 0 /* JERRY */ +#if 1 /* JERRY */ + + /* apparently thr build farm relies upon this heavior :-( */ + return methods->parent->pdb_add_sam_account(methods->parent, newpwd); #else /* I don't think we should allow any modification of diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 446eff9045..b3e6478c88 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -894,7 +894,9 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM /* well-known aliases */ if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) { + become_root(); pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED); + unbecome_root(); if (num_entries != 0) { *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP)); @@ -914,6 +916,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM struct sys_grent *grp; gid_t winbind_gid_low, winbind_gid_high; BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high); + BOOL ret; /* local aliases */ /* we return the UNIX groups here. This seems to be the right */ @@ -930,7 +933,10 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) { uint32 trid; - if(!pdb_getgrgid(&smap, grp->gr_gid)) + become_root(); + ret = pdb_getgrgid(&smap, grp->gr_gid); + unbecome_root(); + if( !ret ) continue; if (smap.sid_name_use!=SID_NAME_ALIAS) { @@ -4111,6 +4117,7 @@ NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAM int num_uids=0; GROUP_INFO_CTR *ctr; uint32 acc_granted; + BOOL ret; if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) return NT_STATUS_INVALID_HANDLE; @@ -4119,7 +4126,10 @@ NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAM return r_u->status; } - if (!get_domain_group_from_sid(group_sid, &map)) + become_root(); + ret = get_domain_group_from_sid(group_sid, &map); + unbecome_root(); + if (!ret) return NT_STATUS_INVALID_HANDLE; ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR)); @@ -4271,6 +4281,7 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G size_t sd_size; NTSTATUS status; fstring sid_string; + BOOL ret; if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) return NT_STATUS_INVALID_HANDLE; @@ -4305,7 +4316,10 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string)); /* check if that group really exists */ - if (!get_domain_group_from_sid(info->sid, &map)) + become_root(); + ret = get_domain_group_from_sid(info->sid, &map); + unbecome_root(); + if (!ret) return NT_STATUS_NO_SUCH_GROUP; /* get a (unique) handle. open a policy on it. */ diff --git a/source3/script/installswat.sh b/source3/script/installswat.sh index 7841a2a7b5..be0cdf3eef 100755 --- a/source3/script/installswat.sh +++ b/source3/script/installswat.sh @@ -28,16 +28,16 @@ done # Install images for ln in $LANGS; do -for f in $SRCDIR../swat/$ln/images/*.gif; do + for f in $SRCDIR../swat/$ln/images/*.gif; do FNAME=$SWATDIR/$ln/images/`basename $f` echo $FNAME cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges? chmod 0644 $FNAME -done + done -# Install html help + # Install html help -for f in $SRCDIR../swat/$ln/help/*.html; do + for f in $SRCDIR../swat/$ln/help/*.html; do FNAME=$SWATDIR/$ln/help/`basename $f` echo $FNAME if [ "x$BOOKDIR" = "x" ]; then @@ -49,28 +49,28 @@ for f in $SRCDIR../swat/$ln/help/*.html; do cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges? rm -f $f chmod 0644 $FNAME -done + done -# Install html documentation + # Install "server-side" includes -for f in $SRCDIR../docs/htmldocs/*.html; do - FNAME=$SWATDIR/help/`basename $f` + for f in $SRCDIR../swat/$ln/include/*.html; do + FNAME=$SWATDIR/$ln/include/`basename $f` echo $FNAME cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges? chmod 0644 $FNAME + done + done -# Install "server-side" includes +# Install html documentation -for f in $SRCDIR../swat/$ln/include/*.html; do - FNAME=$SWATDIR/$ln/include/`basename $f` +for f in $SRCDIR../docs/htmldocs/*.html; do + FNAME=$SWATDIR/help/`basename $f` echo $FNAME cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges? chmod 0644 $FNAME done -done - # Install Using Samba book (but only if it is there) if [ "x$BOOKDIR" != "x" -a -f $SRCDIR../docs/htmldocs/using_samba/toc.html ]; then -- cgit From 30d0680106c74901d6fc0c993c3c4770cd2efb22 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Nov 2003 09:30:21 +0000 Subject: Merge from 3.0: source/passdb/pdb_get_set.c: I agree with vl's #if 0 here, and am not quite sure what I was thinking with regard to the original code. Let's keep samba simple, and just remove it. source/rpc_server/srv_netlog_nt.c: Remove compleatly wrong comments. (There were correct, 2 years ago...) source/intl/lang_tdb.c: Add newline to debug message Andrew Bartlett (This used to be commit 2a8dbe03690b60f3d9c83de3cf6ce873aa0657bc) --- source3/intl/lang_tdb.c | 2 +- source3/passdb/pdb_get_set.c | 13 ------------- source3/rpc_server/srv_netlog_nt.c | 6 ------ 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/source3/intl/lang_tdb.c b/source3/intl/lang_tdb.c index b0e9e414de..b98e5734cb 100644 --- a/source3/intl/lang_tdb.c +++ b/source3/intl/lang_tdb.c @@ -131,7 +131,7 @@ BOOL lang_tdb_init(const char *lang) asprintf(&msg_path, "%s.msg", lib_path((const char *)lang)); if (stat(msg_path, &st) != 0) { /* the msg file isn't available */ - DEBUG(10, ("lang_tdb_init: %s: %s", msg_path, + DEBUG(10, ("lang_tdb_init: %s: %s\n", msg_path, strerror(errno))); goto done; } diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 46c49be8b1..4a5a5759d4 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -1045,19 +1045,6 @@ BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data, if (!sampass) return False; -#if 0 - /* With this check backend_private_data_free_fn is *never* set - as the methods are never set anywhere. What is this - supposed to do ???? - - Volker - */ - - /* does this backend 'own' this SAM_ACCOUNT? */ - if (my_methods != sampass->private.backend_private_methods) - return False; -#endif - if (sampass->private.backend_private_data && sampass->private.backend_private_data_free_fn) { sampass->private.backend_private_data_free_fn(&sampass->private.backend_private_data); } diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 66fa6e7678..5ba3dac669 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -581,8 +581,6 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * return NT_STATUS_INVALID_INFO_CLASS; } /* end switch */ - /* check username exists */ - rpcstr_pull(nt_username,uni_samlogon_user->buffer,sizeof(nt_username),uni_samlogon_user->uni_str_len*2,0); rpcstr_pull(nt_domain,uni_samlogon_domain->buffer,sizeof(nt_domain),uni_samlogon_domain->uni_str_len*2,0); rpcstr_pull(nt_workstation,uni_samlogon_workstation->buffer,sizeof(nt_workstation),uni_samlogon_workstation->uni_str_len*2,0); @@ -593,10 +591,6 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * fstrcpy(current_user_info.smb_name, nt_username); sub_set_smb_name(nt_username); - /* - * Convert to a UNIX username. - */ - DEBUG(5,("Attempting validation level %d for unmapped username %s.\n", q_u->sam_id.ctr->switch_value, nt_username)); status = NT_STATUS_OK; -- cgit From 649f7d749de3f09dca8415fadf1efb3d74f57e0f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 9 Nov 2003 17:24:16 +0000 Subject: From 3_0: Skip over the winbind separator when looking up a user. Volker (This used to be commit efe36a44d3d35f2bbb3381916dfdfda80560b67c) --- source3/auth/auth_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index dd0c0b02dd..d7d7f53e2d 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -972,6 +972,7 @@ struct passwd *smb_getpwnam( char *domuser ) p = strchr( domuser, *lp_winbind_separator() ); if ( p ) { + p += 1; fstrcpy( mapped_username, p ); map_username( mapped_username ); return Get_Pwnam(mapped_username); -- cgit From 912289bd489f70eea345d89dff32f03bd8b8916b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Nov 2003 19:33:40 +0000 Subject: Patch from Andrew Bartlett for security=server core dump if server goes away. Jeremy. (This used to be commit a646cb60a24498451d379967a1da272fcd40875f) --- source3/auth/auth_server.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c index 30e0e13a56..b57293943c 100644 --- a/source3/auth/auth_server.c +++ b/source3/auth/auth_server.c @@ -153,14 +153,16 @@ static void free_server_private_data(void **private_data_pointer) static void send_server_keepalive(void **private_data_pointer) { - struct cli_state **cli = (struct cli_state **)private_data_pointer; - /* also send a keepalive to the password server if its still connected */ - if (cli && *cli && (*cli)->initialised) { - if (!send_keepalive((*cli)->fd)) { - DEBUG( 2, ( "password server keepalive failed.\n")); - cli_shutdown(*cli); + if (private_data_pointer) { + struct cli_state *cli = (struct cli_state *)(*private_data_pointer); + if (cli && cli->initialised) { + if (!send_keepalive(cli->fd)) { + DEBUG( 2, ( "send_server_keepalive: password server keepalive failed.\n")); + cli_shutdown(cli); + *private_data_pointer = NULL; + } } } } -- cgit From 0f98e8ab83b474cba8696aed3abbb64d38f25b95 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 11 Nov 2003 19:22:44 +0000 Subject: fix crash bug due to empyrt munged dial string; patch from metze (This used to be commit aef7f54355a71e36963ed7427e9c2f05d26cc222) --- source3/rpc_parse/parse_misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index b0144c2c89..cd59d390aa 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -1044,7 +1044,7 @@ void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) str->uni_max_len = str->uni_str_len; str->offset = 0; str->buffer = (uint16 *) memdup(blob->data, blob->length); - if (!str->buffer) { + if ((str->buffer == NULL) && (blob->length > 0)) { smb_panic("init_unistr2_from_datablob: malloc fail\n"); } } -- cgit From a40625bc9dc82794c9c8ca40a6095046b95a245e Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 12 Nov 2003 21:47:25 +0000 Subject: > Omit html documentation tree because it has been moved to the separate > module. Install though, in case one recreates the tree as it was before. > > > rafal Same as in SAMBA_3_0 source tree. rafal (This used to be commit af972c76158069efe3817a4e6dce4826d883edf1) --- source3/script/installswat.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source3/script/installswat.sh b/source3/script/installswat.sh index be0cdf3eef..534c2d761f 100755 --- a/source3/script/installswat.sh +++ b/source3/script/installswat.sh @@ -64,12 +64,15 @@ done # Install html documentation -for f in $SRCDIR../docs/htmldocs/*.html; do - FNAME=$SWATDIR/help/`basename $f` - echo $FNAME - cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges? - chmod 0644 $FNAME -done +if [ -d $SRCDIR../docs/htmldocs/ ]; then + + for f in $SRCDIR../docs/htmldocs/*.html; do + FNAME=$SWATDIR/help/`basename $f` + echo $FNAME + cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges? + chmod 0644 $FNAME + done +fi # Install Using Samba book (but only if it is there) -- cgit From bd4e882b0b5e6ae9d64c784b16a3b7fffb6c5e50 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 12 Nov 2003 22:37:09 +0000 Subject: show locked files for -u ; bug 590 (This used to be commit 3290582cb0542d1e2a7e1e5213614fca8788b070) --- source3/utils/status.c | 51 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/source3/utils/status.c b/source3/utils/status.c index c17e080b6b..54dce1ecf0 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -35,10 +35,12 @@ #include "includes.h" -static pstring Ucrit_username = ""; /* added by OH */ -static pid_t Ucrit_pid[100]; /* Ugly !!! */ /* added by OH */ -static int Ucrit_MaxPid=0; /* added by OH */ -static unsigned int Ucrit_IsActive = 0; /* added by OH */ +#define SMB_MAXPIDS 2048 +static pstring Ucrit_username = ""; /* added by OH */ +static pid_t Ucrit_pid[SMB_MAXPIDS]; /* Ugly !!! */ /* added by OH */ +static int Ucrit_MaxPid=0; /* added by OH */ +static unsigned int Ucrit_IsActive = 0; /* added by OH */ + static int verbose, brief; static int shares_only = 0; /* Added by RJS */ static int locks_only = 0; /* Added by RJS */ @@ -49,26 +51,53 @@ static int show_brl; static void Ucrit_addUsername(const char *username) { pstrcpy(Ucrit_username, username); - if(strlen(Ucrit_username) > 0) + + if ( strlen(Ucrit_username) > 0 ) Ucrit_IsActive = 1; } static unsigned int Ucrit_checkUsername(const char *username) { - if ( !Ucrit_IsActive) return 1; - if (strcmp(Ucrit_username,username) ==0) return 1; + if ( !Ucrit_IsActive ) + return 1; + + if ( strcmp(Ucrit_username,username) == 0 ) + return 1; + return 0; } static unsigned int Ucrit_checkPid(pid_t pid) { int i; - if ( !Ucrit_IsActive) return 1; - for (i=0;i= SMB_MAXPIDS ) { + d_printf("ERROR: More than %d pids for user %s!\n", + SMB_MAXPIDS, Ucrit_username); + + return False; + } + + Ucrit_pid[Ucrit_MaxPid++] = pid; + + return True; +} static void print_share_mode(share_mode_entry *e, char *fname) { @@ -526,6 +555,8 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo return 0; } + Ucrit_addPid( sessionid.pid ); + d_printf("%5d %-12s %-12s %-12s (%s)\n", (int)sessionid.pid, uidtoname(sessionid.uid), gidtoname(sessionid.gid), sessionid.remote_machine, sessionid.hostname); -- cgit From 618d7dd0c77cc125611e97d60d6759fb0a0ccb5c Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 13 Nov 2003 17:04:59 +0000 Subject: Keep configure.in in sync with SAMBA-3.0.0 (This used to be commit 664cc4f46cf1be08c704a9d163ee33c8629ad065) --- source3/aclocal.m4 | 33 ++++++++++++++------------------- source3/configure.in | 12 +++++++++++- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/source3/aclocal.m4 b/source3/aclocal.m4 index 5169eee41b..96f265daf2 100644 --- a/source3/aclocal.m4 +++ b/source3/aclocal.m4 @@ -516,7 +516,7 @@ AC_DEFUN(jm_ICONV, dnl those with the standalone portable libiconv installed). AC_MSG_CHECKING(for iconv in $1) jm_cv_func_iconv="no" - jm_cv_lib_iconv=no + jm_cv_lib_iconv="" jm_cv_giconv=no jm_save_LIBS="$LIBS" LIBS="$LIBS -lbiconv" @@ -528,9 +528,10 @@ AC_DEFUN(jm_ICONV, jm_cv_func_iconv=yes jm_cv_biconv=yes jm_cv_include="biconv.h" - jm_cv_lib_iconv="yes") + jm_cv_lib_iconv="biconv") LIBS="$jm_save_LIBS" + dnl Check for include in funny place but no lib needed if test "$jm_cv_func_iconv" != yes; then AC_TRY_LINK([#include #include ], @@ -539,8 +540,10 @@ AC_DEFUN(jm_ICONV, iconv_close(cd);], jm_cv_func_iconv=yes jm_cv_include="giconv.h" - jm_cv_giconv="yes") + jm_cv_giconv="yes" + jm_cv_lib_iconv="") + dnl Standard iconv.h include, lib in glibc or libc ... if test "$jm_cv_func_iconv" != yes; then AC_TRY_LINK([#include #include ], @@ -548,7 +551,8 @@ AC_DEFUN(jm_ICONV, iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], jm_cv_include="iconv.h" - jm_cv_func_iconv=yes) + jm_cv_func_iconv=yes + jm_cv_lib_iconv="") if test "$jm_cv_lib_iconv" != yes; then jm_save_LIBS="$LIBS" @@ -561,8 +565,10 @@ AC_DEFUN(jm_ICONV, jm_cv_lib_iconv=yes jm_cv_func_iconv=yes jm_cv_include="giconv.h" - jm_cv_giconv=yes) - LIBS="$jm_save_LIBS" + jm_cv_giconv=yes + jm_cv_lib_iconv="giconv") + + LIBS="$jm_save_LIBS" if test "$jm_cv_func_iconv" != yes; then jm_save_LIBS="$LIBS" @@ -572,9 +578,9 @@ AC_DEFUN(jm_ICONV, [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], - jm_cv_lib_iconv=yes jm_cv_include="iconv.h" - jm_cv_func_iconv=yes) + jm_cv_func_iconv=yes + jm_cv_lib_iconv="iconv") LIBS="$jm_save_LIBS" fi fi @@ -599,17 +605,6 @@ AC_DEFUN(jm_ICONV, else AC_MSG_RESULT(no) fi - if test "$jm_cv_lib_iconv" = yes; then - if test "$jm_cv_giconv" = yes; then - LIBS="$LIBS -lgiconv" - else - if test "$jm_cv_biconv" = yes; then - LIBS="$LIBS -lbiconv" - else - LIBS="$LIBS -liconv" - fi - fi - fi ]) AC_DEFUN(rjs_CHARSET,[ diff --git a/source3/configure.in b/source3/configure.in index 269fdf97ed..2c1880f3b2 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1617,7 +1617,7 @@ dnl Try to find iconv(3) LDFLAGS=$save_LDFLAG LIB_ADD_DIR(LDFLAGS, "$i/lib") CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") - LIBS="$save_LIBS" + LIBS="$save_LIBS" ICONV_LOCATION=$i export LDFLAGS LIBS CPPFLAGS dnl Now, check for a working iconv ... we want to do it here because @@ -1629,6 +1629,9 @@ dnl there might be a working iconv further down the list of LOOK_DIRS if test x"$ICONV_PATH_SPEC" = "xyes" ; then LIBS="$LIBS -L$ICONV_LOCATION/lib" fi + if test x"$jm_cv_lib_iconv" != x; then + LIBS="$LIBS -l$jm_cv_lib_iconv" + fi dnl AC_CACHE_CHECK([for working iconv],samba_cv_HAVE_NATIVE_ICONV,[ default_dos_charset=no default_display_charset=no @@ -1683,6 +1686,13 @@ dnl ]) if test x"$samba_cv_HAVE_NATIVE_ICONV" = x"yes"; then CPPFLAGS=$save_CPPFLAGS CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") + LIBS=$save_LIBS + if test x"$jm_cv_lib_iconv" != x; then + LIBS="$LIBS -l$jm_cv_lib_iconv" + fi + dnl Add the flags we need to CPPFLAGS and LDFLAGS + CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") + LIB_ADD_DIR(LDFLAGS, "$i/lib") export CPPFLAGS AC_DEFINE(HAVE_NATIVE_ICONV,1,[Whether to use native iconv]) AC_DEFINE_UNQUOTED(DEFAULT_DOS_CHARSET,$default_dos_charset,[Default dos charset name]) -- cgit From ac20c8cfb0e3633f5007fe30fe82704264db5c00 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 13 Nov 2003 20:16:28 +0000 Subject: * Fix from SATOH Fumiyasu for bug 660 (failing to view print jobs) by only enforce the 'max reported print jobs' parameter when it is non-zero. * Fixed bug 338 by making sure that data values are written out when we are marshalling an EnumPrinterDataEx() reply. This probably fixes other bugs reported against point-n-print feature in 3.0.0 (This used to be commit d7026f6d178f6ed531bbf7d681d4efde0828616c) --- source3/printing/printing.c | 4 ++-- source3/rpc_parse/parse_spoolss.c | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1a878afb92..ef532473ba 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -849,7 +849,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct size_t i; uint qcount; - if (max_reported_jobs < pts->qcount) + if (max_reported_jobs && (max_reported_jobs < pts->qcount)) pts->qcount = max_reported_jobs; qcount = pts->qcount; @@ -2146,7 +2146,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun len = 0; for( i = 0; i < qcount; i++) { uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime; - len += tdb_unpack(data.dptr + 4 + len, data.dsize - len, NULL, "ddddddff", + len += tdb_unpack(data.dptr + 4 + len, data.dsize - len, "ddddddff", &qjob, &qsize, &qpage_count, diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 65f16414a0..7581316767 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -7294,11 +7294,13 @@ static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename)) return False; - if (UNMARSHALLING(ps) && ctr->values[i].data_len) { - ctr->values[i].data = (uint8 *)prs_alloc_mem( - ps, ctr->values[i].data_len); - if (!ctr->values[i].data) - return False; + if ( ctr->values[i].data_len ) { + if ( UNMARSHALLING(ps) ) { + ctr->values[i].data = (uint8 *)prs_alloc_mem( + ps, ctr->values[i].data_len); + if (!ctr->values[i].data) + return False; + } if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len)) return False; } -- cgit From d3d4c7446e43a484535ea05a6fb3234d78199e95 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 13 Nov 2003 21:40:27 +0000 Subject: Add this to samba-head. (This used to be commit d761175f131f80ae24549adca6ffc629f84a9803) --- examples/libsmbclient/testacl.c | 280 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 examples/libsmbclient/testacl.c diff --git a/examples/libsmbclient/testacl.c b/examples/libsmbclient/testacl.c new file mode 100644 index 0000000000..47668f7c9c --- /dev/null +++ b/examples/libsmbclient/testacl.c @@ -0,0 +1,280 @@ +#include +#include +#include +#include +#include "libsmbclient.h" + +enum acl_mode +{ + SMB_ACL_GET, + SMB_ACL_SET, + SMB_ACL_DELETE, + SMB_ACL_MODIFY, + SMB_ACL_ADD, + SMB_ACL_CHOWN, + SMB_ACL_CHGRP +}; + +static void +get_auth_data_fn(const char * pServer, + const char * pShare, + char * pWorkgroup, + int maxLenWorkgroup, + char * pUsername, + int maxLenUsername, + char * pPassword, + int maxLenPassword) + +{ + char temp[128]; + + fprintf(stdout, "Workgroup: [%s] ", pWorkgroup); + fgets(temp, sizeof(temp), stdin); + + if (temp[strlen(temp) - 1] == '\n') /* A new line? */ + { + temp[strlen(temp) - 1] = '\0'; + } + + if (temp[0] != '\0') + { + strncpy(pWorkgroup, temp, maxLenWorkgroup - 1); + } + + fprintf(stdout, "Username: [%s] ", pUsername); + fgets(temp, sizeof(temp), stdin); + + if (temp[strlen(temp) - 1] == '\n') /* A new line? */ + { + temp[strlen(temp) - 1] = '\0'; + } + + if (temp[0] != '\0') + { + strncpy(pUsername, temp, maxLenUsername - 1); + } + + fprintf(stdout, "Password: "); + fgets(temp, sizeof(temp), stdin); + + if (temp[strlen(temp) - 1] == '\n') /* A new line? */ + { + temp[strlen(temp) - 1] = '\0'; + } + + if (temp[0] != '\0') + { + strncpy(pPassword, temp, maxLenPassword - 1); + } +} + + +int main(int argc, const char *argv[]) +{ + int opt; + int flags; + int debug = 0; + int numeric = 0; + enum acl_mode mode = SMB_ACL_GET; + static char *the_acl = NULL; + int ret; + char *p; + char *debugstr; + char path[1024]; + char value[1024]; + poptContext pc; + struct poptOption long_options[] = + { + POPT_AUTOHELP + { + "numeric", 'n', POPT_ARG_NONE, &numeric, + 1, "Don't resolve sids or masks to names" + }, + { + "debug", 'd', POPT_ARG_INT, &debug, + 0, "Set debug level (0-100)" + }, + { + "delete", 'D', POPT_ARG_STRING, NULL, + 'D', "Delete an acl", "ACL" + }, + { + "modify", 'M', POPT_ARG_STRING, NULL, + 'M', "Modify an acl", "ACL" + }, + { + "add", 'a', POPT_ARG_STRING, NULL, + 'a', "Add an acl", "ACL" + }, + { + "set", 'S', POPT_ARG_STRING, NULL, + 'S', "Set acls", "ACLS" + }, + { + "chown", 'C', POPT_ARG_STRING, NULL, + 'C', "Change ownership of a file", "USERNAME" + }, + { + "chgrp", 'G', POPT_ARG_STRING, NULL, + 'G', "Change group ownership of a file", "GROUPNAME" + }, + { + "get", 'g', POPT_ARG_STRING, NULL, + 'g', "Get a specific acl attribute", "ACL" + }, + { + NULL + } + }; + + setbuf(stdout, NULL); + + pc = poptGetContext("smbcacls", argc, argv, long_options, 0); + + poptSetOtherOptionHelp(pc, "smb://server1/share1/filename"); + + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + case 'S': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_SET; + break; + + case 'D': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_DELETE; + break; + + case 'M': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_MODIFY; + break; + + case 'a': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_ADD; + break; + + case 'g': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_GET; + break; + + case 'C': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_CHOWN; + break; + + case 'G': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_CHGRP; + break; + } + } + + /* Make connection to server */ + if(!poptPeekArg(pc)) { + poptPrintUsage(pc, stderr, 0); + return 1; + } + + strcpy(path, poptGetArg(pc)); + + if (smbc_init(get_auth_data_fn, debug) != 0) + { + printf("Could not initialize smbc_ library\n"); + return 1; + } + + /* Perform requested action */ + + switch(mode) + { + case SMB_ACL_GET: + if (the_acl == NULL) + { + if (numeric) + { + the_acl = "system.nt_sec_desc.*"; + } + else + { + the_acl = "system.nt_sec_desc.*+"; + } + } + ret = smbc_getxattr(path, the_acl, value, sizeof(value)); + if (ret < 0) + { + printf("Could not get attributes for [%s] %d: %s\n", + path, errno, strerror(errno)); + return 1; + } + + printf("Attributes for [%s] are:\n%s\n", path, value); + break; + + case SMB_ACL_ADD: + flags = SMBC_XATTR_FLAG_CREATE; + debugstr = "add attributes"; + goto do_set; + + case SMB_ACL_MODIFY: + flags = SMBC_XATTR_FLAG_REPLACE; + debugstr = "modify attributes"; + goto do_set; + + case SMB_ACL_CHOWN: + snprintf(value, sizeof(value), + "system.nt_sec_desc.owner%s:%s", + numeric ? "" : "+", the_acl); + the_acl = value; + debugstr = "chown owner"; + goto do_set; + + case SMB_ACL_CHGRP: + snprintf(value, sizeof(value), + "system.nt_sec_desc.group%s:%s", + numeric ? "" : "+", the_acl); + the_acl = value; + debugstr = "change group"; + goto do_set; + + case SMB_ACL_SET: + flags = 0; + debugstr = "set attributes"; + + do_set: + if ((p = strchr(the_acl, ':')) == NULL) + { + printf("Missing value. ACL must be name:value pair\n"); + return 1; + } + + *p++ = '\0'; + + ret = smbc_setxattr(path, the_acl, p, strlen(p), flags); + if (ret < 0) + { + printf("Could not %s for [%s] %d: %s\n", + debugstr, path, errno, strerror(errno)); + return 1; + } + break; + + case SMB_ACL_DELETE: + ret = smbc_removexattr(path, the_acl); + if (ret < 0) + { + printf("Could not remove attribute %s for [%s] %d:%s\n", + the_acl, path, errno, strerror(errno)); + return 1; + } + break; + + default: + printf("operation not yet implemented\n"); + break; + } + + return 0; +} -- cgit From 716dd32809b1fe2e6a836700297145c170d103c0 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 13 Nov 2003 21:42:07 +0000 Subject: Update Makefile ... (This used to be commit b92fd87b2461dff0e05ad4a7b0a475539c21d4c0) --- examples/libsmbclient/Makefile | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/libsmbclient/Makefile b/examples/libsmbclient/Makefile index 5fe9977c0a..c84cc3c977 100644 --- a/examples/libsmbclient/Makefile +++ b/examples/libsmbclient/Makefile @@ -2,12 +2,15 @@ CC = gcc SAMBA_INCL = ../../source/include +EXTLIB_INCL = -I/usr/include/gtk-1.2 \ + -I/usr/include/glib-1.2 \ + -I/usr/lib/glib/include -CFLAGS = -I$(SAMBA_INCL) +CFLAGS = -I$(SAMBA_INCL) $(EXTLIB_INCL) LDFLAGS = -L/usr/lib -all: testsmbc tree +all: testsmbc tree testacl testsmbc: testsmbc.o @echo Linking testsmbc @@ -21,5 +24,9 @@ tree: tree.o @echo Linking tree @$(CC) `gtk-config --cflags` $(CFLAGS) $(LDFLAGS) -o $@ `gtk-config --libs` -lsmbclient $< +testacl: testacl.o + @echo Linking testacl + @$(CC) `gtk-config --cflags` $(CFLAGS) $(LDFLAGS) -o $@ `gtk-config --libs` -lsmbclient -lpopt $< + clean: @rm -f *.o *~ -- cgit From 7301471a6a12244cd398e3c81c310ffc2b663c53 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 14 Nov 2003 03:36:27 +0000 Subject: fix more memory leaks in the LDAP backend code; patches from metze (This used to be commit 89a8c607af4ca67fcefe285480f7c9b832f6720c) --- source3/configure.in | 1 - source3/passdb/pdb_ldap.c | 60 ++++++++++++++++++++++++++++++----------------- source3/sam/idmap_ldap.c | 18 ++++++++++---- 3 files changed, 52 insertions(+), 27 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 2c1880f3b2..8093e341ae 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1636,7 +1636,6 @@ dnl AC_CACHE_CHECK([for working iconv],samba_cv_HAVE_NATIVE_ICONV,[ default_dos_charset=no default_display_charset=no default_unix_charset=no - echo # check for default dos charset name for j in CP850 IBM850 ; do diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 9299ca2e50..023e9f3fe0 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -5,7 +5,7 @@ Copyright (C) Gerald Carter 2001-2003 Copyright (C) Shahms King 2001 Copyright (C) Andrew Bartlett 2002-2003 - Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Stefan (metze) Metzmacher 2002-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 @@ -258,7 +258,7 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state, char **attrs) { int rc; - LDAPMessage *entry; + LDAPMessage *entry = NULL; LDAPMod **mods = NULL; char *name, *dn; BerElement *ptr = NULL; @@ -1017,8 +1017,8 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - LDAPMessage *result; - LDAPMessage *entry; + LDAPMessage *result = NULL; + LDAPMessage *entry = NULL; int count; char ** attr_list; int rc; @@ -1099,8 +1099,8 @@ static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state, static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - LDAPMessage *result; - LDAPMessage *entry; + LDAPMessage *result = NULL; + LDAPMessage *entry = NULL; int count; int rc; fstring sid_string; @@ -1264,7 +1264,7 @@ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_A struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; const char *sname; int rc; - LDAPMessage *result; + LDAPMessage *result = NULL; NTSTATUS ret; char **attr_list; fstring objclass; @@ -1328,9 +1328,9 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc = 0; char *dn; - LDAPMessage *result; - LDAPMessage *entry; - LDAPMod **mods; + LDAPMessage *result = NULL; + LDAPMessage *entry = NULL; + LDAPMod **mods = NULL; char **attr_list; result = pdb_get_backend_private_data(newpwd, my_methods); @@ -1361,13 +1361,14 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A element_is_changed)) { DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n")); SAFE_FREE(dn); + if (mods != NULL) + ldap_mods_free(mods,True); return NT_STATUS_UNSUCCESSFUL; } if (mods == NULL) { DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n", pdb_get_username(newpwd))); - ldap_mods_free(mods, True); SAFE_FREE(dn); return NT_STATUS_OK; } @@ -1458,6 +1459,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n", sid_to_string(sid_string, sid))); free_attr_list( attr_list ); + ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; } ldap_msgfree(result); @@ -1514,6 +1516,11 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO LDAP_OBJ_IDMAP_ENTRY, LDAP_OBJ_SID_ENTRY); + /* free old result before doing a new search */ + if (result != NULL) { + ldap_msgfree(result); + result = NULL; + } rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr_list, &result); @@ -1566,6 +1573,8 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO element_is_set_or_changed)) { DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n")); ldap_msgfree(result); + if (mods != NULL) + ldap_mods_free(mods,True); return NT_STATUS_UNSUCCESSFUL; } @@ -1626,9 +1635,9 @@ static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state, ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); DEBUG(0, ("ldapsam_search_one_group: " - "Problem during the LDAP search: LDAP error: %s (%s)", + "Problem during the LDAP search: LDAP error: %s (%s)\n", ld_error?ld_error:"(unknown)", ldap_err2string(rc))); - DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n", + DEBUGADD(3, ("ldapsam_search_one_group: Query was: %s, %s\n", lp_ldap_group_suffix(), filter)); SAFE_FREE(ld_error); } @@ -1745,8 +1754,8 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods, { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data; - LDAPMessage *result; - LDAPMessage *entry; + LDAPMessage *result = NULL; + LDAPMessage *entry = NULL; int count; if (ldapsam_search_one_group(ldap_state, filter, &result) @@ -1957,10 +1966,10 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods, struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data; int rc; - char *dn; - LDAPMessage *result; - LDAPMessage *entry; - LDAPMod **mods; + char *dn = NULL; + LDAPMessage *result = NULL; + LDAPMessage *entry = NULL; + LDAPMod **mods = NULL; rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result); @@ -1980,6 +1989,8 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods, result, &mods, map)) { DEBUG(0, ("ldapsam_update_group_mapping_entry: init_ldap_from_group failed\n")); ldap_msgfree(result); + if (mods != NULL) + ldap_mods_free(mods,True); return NT_STATUS_UNSUCCESSFUL; } @@ -2022,7 +2033,7 @@ static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods, { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data; pstring sidstring, filter; - LDAPMessage *result; + LDAPMessage *result = NULL; int rc; NTSTATUS ret; char **attr_list; @@ -2176,6 +2187,11 @@ static void free_private_data(void **vp) smbldap_free_struct(&(*ldap_state)->smbldap_state); + if ((*ldap_state)->result != NULL) { + ldap_msgfree((*ldap_state)->result); + (*ldap_state)->result = NULL; + } + *ldap_state = NULL; /* No need to free any further, as it is talloc()ed */ @@ -2342,8 +2358,8 @@ and will risk BDCs having inconsistant SIDs\n")); alg_rid_base_string)) { alg_rid_base = (uint32)atol(alg_rid_base_string); if (alg_rid_base != algorithmic_rid_base()) { - DEBUG(0, ("pdb_init_ldapsam: The value of 'algorithmic RID base' has changed since the LDAP\n\ -database was initialised. Aborting. \n")); + DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n" + "database was initialised. Aborting. \n")); ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/sam/idmap_ldap.c b/source3/sam/idmap_ldap.c index 2a94de755a..db1bb74de5 100644 --- a/source3/sam/idmap_ldap.c +++ b/source3/sam/idmap_ldap.c @@ -234,6 +234,7 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, next_rid = *rid+1; if (next_rid >= alg_rid_base) { + ldap_msgfree(domain_result); return NT_STATUS_UNSUCCESSFUL; } @@ -382,7 +383,7 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) pstring id_str, new_id_str; LDAPMod **mods = NULL; const char *type; - char *dn; + char *dn = NULL; char **attr_list; pstring filter; uid_t luid, huid; @@ -455,12 +456,15 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) smbldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str ); smbldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str ); - + + if (mods == NULL) { + DEBUG(0,("ldap_allocate_id: smbldap_set_mod() failed.\n")); + goto out; + } + rc = smbldap_modify(ldap_state.smbldap_state, dn, mods); - SAFE_FREE(dn); ldap_mods_free( mods, True ); - if (rc != LDAP_SUCCESS) { DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n", type)); @@ -469,6 +473,10 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) ret = NT_STATUS_OK; out: + SAFE_FREE(dn); + if (result != NULL) + ldap_msgfree(result); + return ret; } @@ -683,6 +691,8 @@ static NTSTATUS verify_idpool( void ) count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); + ldap_msgfree(result); + if ( count > 1 ) { DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n", filter, lp_ldap_idmap_suffix() )); -- cgit From e762e323897cd4ba3445016b6904136264082d25 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 15 Nov 2003 00:47:29 +0000 Subject: Split smbldap in a core file and a utility file Add module support for configuration loading Add a first implementation of config_ldap module to put samba configuration on ldap It worked on my test machine, please try it out and send bugfixes :-) have fun, Simo. INSTRUCTIONS: Just add something like this to your smb.conf file: config backend = config_ldap:ldap://localhost config_ldap:basedn = dc=samba,dc=org the config tree must follow this scheme: ou=foo, dc=samba, dc=org <- global section |- sambaOptionName=log level, ou=foo, ... <- options |- ... |- sambaShareName=testlc, ou=foo, ... == [testlc] |- sambaOptionName=path, sambaShareName=testlc, ou=foo, ... <- option here is a sample ldif: # foo, samba, org dn: ou=foo, dc=samba, dc=org objectClass: organizationalUnit objectClass: sambaConfig ou: foo description: Test Foo # log level, foo, samba, org dn: sambaOptionName=log level, ou=foo, dc=samba, dc=org objectClass: sambaConfigOption sambaOptionName: log level sambaIntegerOption: 10 description: log level 10 is suitable for good debugging # testlc, foo, samba, org dn: sambaShareName=testlc, ou=foo, dc=samba, dc=org objectClass: sambaShare sambaShareName: testlc description: share to test ldap config module actually works # path, testlc, foo, samba, org dn: sambaOptionName=path, sambaShareName=testlc, ou=foo, dc=samba, dc=org objectClass: sambaConfigOption sambaOptionName: path sambaStringOption: /tmp description: Path for share testlc # read only, testlc, foo, samba, org dn: sambaOptionName=read only, sambaShareName=testlc, ou=foo, dc=samba, dc=org objectClass: sambaConfigOption sambaOptionName: read only sambaBoolOption: TRUE description: Share testlc is read only # guest ok, testlc, foo, samba, org dn: sambaOptionName=guest ok, sambaShareName=testlc, ou=foo, dc=samba, dc=org objectClass: sambaConfigOption sambaOptionName: guest ok sambaBoolOption: TRUE description: Guest users are allowed to connect to testlc share (This used to be commit 207968eafc2c2a185e50e2132702d7bab2142aba) --- source3/Makefile.in | 16 +- source3/configure.in | 10 +- source3/include/includes.h | 1 + source3/include/modconf.h | 34 +++++ source3/lib/smbldap.c | 175 ---------------------- source3/lib/smbldap_util.c | 203 +++++++++++++++++++++++++ source3/param/config_ldap.c | 354 ++++++++++++++++++++++++++++++++++++++++++++ source3/param/loadparm.c | 10 ++ source3/param/modconf.c | 96 ++++++++++++ 9 files changed, 720 insertions(+), 179 deletions(-) create mode 100644 source3/include/modconf.h create mode 100644 source3/lib/smbldap_util.c create mode 100644 source3/param/config_ldap.c create mode 100644 source3/param/modconf.c diff --git a/source3/Makefile.in b/source3/Makefile.in index f7e13220c4..6141fd500b 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -66,6 +66,7 @@ RPCLIBDIR = $(LIBDIR)/rpc IDMAPLIBDIR = $(LIBDIR)/idmap CHARSETLIBDIR = $(LIBDIR)/charset AUTHLIBDIR = $(LIBDIR)/auth +CONFIGLIBDIR = $(LIBDIR)/config CONFIGDIR = @configdir@ VARDIR = @localstatedir@ MANDIR = @mandir@ @@ -154,7 +155,8 @@ RPC_MODULES = @RPC_MODULES@ IDMAP_MODULES = @IDMAP_MODULES@ CHARSET_MODULES = @CHARSET_MODULES@ AUTH_MODULES = @AUTH_MODULES@ -MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSET_MODULES) $(AUTH_MODULES) +CONFIG_MODULES = @CONFIG_MODULES@ +MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSET_MODULES) $(AUTH_MODULES) $(CONFIG_MODULES) ###################################################################### # object file lists @@ -163,7 +165,7 @@ MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSE TDBBASE_OBJ = tdb/tdb.o tdb/spinlock.o TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o tdb/tdbback.o -SMBLDAP_OBJ = @SMBLDAP@ +SMBLDAP_OBJ = @SMBLDAP@ @SMBLDAPUTIL@ LIB_OBJ = lib/version.o lib/charcnv.o lib/debug.o lib/fault.o \ lib/getsmbpass.o lib/interface.o lib/md4.o \ @@ -198,7 +200,7 @@ POPT_LIB_OBJ = lib/popt_common.o UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \ ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o -PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o +PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o param/modconf.o KRBCLIENT_OBJ = libads/kerberos.o @@ -340,6 +342,8 @@ AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/auth_compat.o \ MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_map.o smbd/mangle_hash2.o +CONFIG_LDAP_OBJ = param/config_ldap.o + SMBD_OBJ_MAIN = smbd/server.o BUILDOPT_OBJ = smbd/build_options.o @@ -1155,6 +1159,11 @@ bin/cap.@SHLIBEXT@: $(VFS_CAP_OBJ:.o=.@PICSUFFIX@) @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_CAP_OBJ:.o=.@PICSUFFIX@) \ @SONAMEFLAG@`basename $@` +bin/config_ldap.@SHLIBEXT@: $(CONFIG_LDAP_OBJ:.o=.@PICSUFFIX@) + @echo "Building plugin $@" + @$(SHLD) $(LDSHFLAGS) -o $@ $(CONFIG_LDAP_OBJ:.o=.@PICSUFFIX@) \ + @SMBLDAP@ @LDAP_LIBS@ @SONAMEFLAG@`basename $@` + bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@ @@ -1223,6 +1232,7 @@ installmodules: modules installdirs @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(IDMAPLIBDIR) $(IDMAP_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CHARSETLIBDIR) $(CHARSET_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(AUTHLIBDIR) $(AUTH_MODULES) + @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CONFIGLIBDIR) $(CONFIG_MODULES) @# These symlinks are required for the 'probing' of modules. @# This mechanism should go at some point.. @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(PDBLIBDIR) ldapsam.@SHLIBEXT@ ldapsam_compat.@SHLIBEXT@ diff --git a/source3/configure.in b/source3/configure.in index 8093e341ae..b8c8eeaaa0 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -162,6 +162,7 @@ AC_SUBST(SMBWRAPPER) AC_SUBST(EXTRA_BIN_PROGS) AC_SUBST(EXTRA_SBIN_PROGS) AC_SUBST(EXTRA_ALL_TARGETS) +AC_SUBST(CONFIG_LIBS) AC_ARG_ENABLE(debug, [ --enable-debug Turn on compiler debugging information (default=no)], @@ -299,7 +300,7 @@ dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_epmapper auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin pdb_gums gums_tdbsam2" dnl These are preferably build shared, and static if dlopen() is not available -default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap charset_CP850 charset_CP437" +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap charset_CP850 charset_CP437 config_ldap" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_echo" @@ -2288,6 +2289,8 @@ AC_MSG_RESULT($with_ldap_support) SMBLDAP="" AC_SUBST(SMBLDAP) +SMBLDAPUTIL="" +AC_SUBST(SMBLDAPUTIL) if test x"$with_ldap_support" != x"no"; then ################################################################## @@ -2343,7 +2346,9 @@ if test x"$with_ldap_support" != x"no"; then if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available]) default_static_modules="$default_static_modules pdb_ldap idmap_ldap"; + default_shared_modules="$default_shared_modules config_ldap"; SMBLDAP="lib/smbldap.o" + SMBLDAPUTIL="lib/smbldap_util.o" with_ldap_support=yes AC_MSG_CHECKING(whether LDAP support is used) AC_MSG_RESULT(yes) @@ -4194,6 +4199,9 @@ SMB_MODULE(vfs_readonly, \$(VFS_READONLY_OBJ), "bin/readonly.$SHLIBEXT", VFS) SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS) SMB_SUBSYSTEM(VFS,smbd/vfs.o) +SMB_MODULE(config_ldap, param/config_ldap.o, "bin/config_ldap.$SHLIBEXT", CONFIG, [ CONFIG_LIBS="$CONFIG_LIBS $LDAP_LIBS" "$SMBLDAP" ]) +SMB_SUBSYSTEM(CONFIG, param/modconf.o) + AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules]) ################################################# diff --git a/source3/include/includes.h b/source3/include/includes.h index c463f99a90..92c5f847dd 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -890,6 +890,7 @@ struct smb_ldap_privates; /* forward declarations from smbldap.c */ #include "smbldap.h" +#include "modconf.h" /***** automatically generated prototypes *****/ #ifndef NO_PROTO_H diff --git a/source3/include/modconf.h b/source3/include/modconf.h new file mode 100644 index 0000000000..f5cc5ef488 --- /dev/null +++ b/source3/include/modconf.h @@ -0,0 +1,34 @@ +#ifndef _MODCONF_H_ +#define _MODCONF_H_ +/* + Unix SMB/CIFS implementation. + + ModConf headers + + Copyright (C) Simo Sorce 2003 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#define SAMBA_CONFIG_INTERFACE_VERSION 1 + +/* Filled out by config backends */ +struct config_functions { + NTSTATUS (*init)(char *params); + NTSTATUS (*load)(BOOL (*sfunc)(const char *),BOOL (*pfunc)(const char *, const char *)); + NTSTATUS (*close)(void); +}; +#endif /* _MODCONF_H_ */ diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index fe34cfb852..ac35ed2a03 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -1153,181 +1153,6 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_ return NT_STATUS_OK; } -/********************************************************************** - Add the sambaDomain to LDAP, so we don't have to search for this stuff - again. This is a once-add operation for now. - - TODO: Add other attributes, and allow modification. -*********************************************************************/ -static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, - const char *domain_name) -{ - fstring sid_string; - fstring algorithmic_rid_base_string; - pstring filter, dn; - LDAPMod **mods = NULL; - int rc; - int ldap_op; - LDAPMessage *result = NULL; - int num_result; - char **attr_list; - uid_t u_low, u_high; - gid_t g_low, g_high; - uint32 rid_low, rid_high; - - slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))", - get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), - domain_name, LDAP_OBJ_DOMINFO); - - attr_list = get_attr_list( dominfo_attr_list ); - rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result); - free_attr_list( attr_list ); - - if (rc != LDAP_SUCCESS) { - return NT_STATUS_UNSUCCESSFUL; - } - - num_result = ldap_count_entries(ldap_state->ldap_struct, result); - - if (num_result > 1) { - DEBUG (0, ("More than domain with that name exists: bailing out!\n")); - ldap_msgfree(result); - return NT_STATUS_UNSUCCESSFUL; - } - - /* Check if we need to add an entry */ - DEBUG(3,("Adding new domain\n")); - ldap_op = LDAP_MOD_ADD; - - pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), - domain_name, lp_ldap_suffix()); - - /* Free original search */ - ldap_msgfree(result); - - /* make the changes - the entry *must* not already have samba attributes */ - smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), - domain_name); - - /* If we don't have an entry, then ask secrets.tdb for what it thinks. - It may choose to make it up */ - - sid_to_string(sid_string, get_global_sam_sid()); - smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), sid_string); - - slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string) - 1, "%i", algorithmic_rid_base()); - smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE), - algorithmic_rid_base_string); - smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO); - - /* add the sambaNext[User|Group]Rid attributes if the idmap ranges are set. - TODO: fix all the places where the line between idmap and normal operations - needed by smbd gets fuzzy --jerry 2003-08-11 */ - - if ( lp_idmap_uid(&u_low, &u_high) && lp_idmap_gid(&g_low, &g_high) - && get_free_rid_range(&rid_low, &rid_high) ) - { - fstring rid_str; - - fstr_sprintf( rid_str, "%i", rid_high|USER_RID_TYPE ); - DEBUG(10,("setting next available user rid [%s]\n", rid_str)); - smbldap_set_mod(&mods, LDAP_MOD_ADD, - get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), - rid_str); - - fstr_sprintf( rid_str, "%i", rid_high|GROUP_RID_TYPE ); - DEBUG(10,("setting next available group rid [%s]\n", rid_str)); - smbldap_set_mod(&mods, LDAP_MOD_ADD, - get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), - rid_str); - - } - - - switch(ldap_op) - { - case LDAP_MOD_ADD: - rc = smbldap_add(ldap_state, dn, mods); - break; - case LDAP_MOD_REPLACE: - rc = smbldap_modify(ldap_state, dn, mods); - break; - default: - DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op)); - return NT_STATUS_INVALID_PARAMETER; - } - - if (rc!=LDAP_SUCCESS) { - char *ld_error = NULL; - ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); - DEBUG(1,("failed to %s domain dn= %s with: %s\n\t%s\n", - ldap_op == LDAP_MOD_ADD ? "add" : "modify", - dn, ldap_err2string(rc), - ld_error?ld_error:"unknown")); - SAFE_FREE(ld_error); - - ldap_mods_free(mods, True); - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(2,("added: domain = %s in the LDAP database\n", domain_name)); - ldap_mods_free(mods, True); - return NT_STATUS_OK; -} - -/********************************************************************** -Search for the domain info entry -*********************************************************************/ -NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, - LDAPMessage ** result, const char *domain_name, - BOOL try_add) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - pstring filter; - int rc; - char **attr_list; - int count; - - pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", - LDAP_OBJ_DOMINFO, - get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), - domain_name); - - DEBUG(2, ("Searching for:[%s]\n", filter)); - - - attr_list = get_attr_list( dominfo_attr_list ); - rc = smbldap_search_suffix(ldap_state, filter, attr_list , result); - free_attr_list( attr_list ); - - if (rc != LDAP_SUCCESS) { - DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc))); - DEBUG(2,("Query was: %s, %s\n", lp_ldap_suffix(), filter)); - } else if (ldap_count_entries(ldap_state->ldap_struct, *result) < 1) { - DEBUG(3, ("Got no domain info entries for domain\n")); - ldap_msgfree(*result); - *result = NULL; - if (try_add && NT_STATUS_IS_OK(ret = add_new_domain_info(ldap_state, domain_name))) { - return smbldap_search_domain_info(ldap_state, result, domain_name, False); - } - else { - DEBUG(0, ("Adding domain info for %s failed with %s\n", - domain_name, nt_errstr(ret))); - return ret; - } - } else if ((count = ldap_count_entries(ldap_state->ldap_struct, *result)) > 1) { - DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n", - count, domain_name)); - ldap_msgfree(*result); - *result = NULL; - return ret; - } else { - return NT_STATUS_OK; - } - - return ret; -} - /******************************************************************* Return a copy of the DN for a LDAPMessage. Convert from utf8 to CH_UNIX. ********************************************************************/ diff --git a/source3/lib/smbldap_util.c b/source3/lib/smbldap_util.c new file mode 100644 index 0000000000..f6097599bc --- /dev/null +++ b/source3/lib/smbldap_util.c @@ -0,0 +1,203 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + Copyright (C) Jean François Micouleau 1998 + Copyright (C) Gerald Carter 2001-2003 + Copyright (C) Shahms King 2001 + Copyright (C) Andrew Bartlett 2002-2003 + Copyright (C) Stefan (metze) Metzmacher 2002-2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "includes.h" +#include "smbldap.h" + +/********************************************************************** + Add the sambaDomain to LDAP, so we don't have to search for this stuff + again. This is a once-add operation for now. + + TODO: Add other attributes, and allow modification. +*********************************************************************/ +static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, + const char *domain_name) +{ + fstring sid_string; + fstring algorithmic_rid_base_string; + pstring filter, dn; + LDAPMod **mods = NULL; + int rc; + int ldap_op; + LDAPMessage *result = NULL; + int num_result; + char **attr_list; + uid_t u_low, u_high; + gid_t g_low, g_high; + uint32 rid_low, rid_high; + + slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))", + get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), + domain_name, LDAP_OBJ_DOMINFO); + + attr_list = get_attr_list( dominfo_attr_list ); + rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result); + free_attr_list( attr_list ); + + if (rc != LDAP_SUCCESS) { + return NT_STATUS_UNSUCCESSFUL; + } + + num_result = ldap_count_entries(ldap_state->ldap_struct, result); + + if (num_result > 1) { + DEBUG (0, ("More than domain with that name exists: bailing out!\n")); + ldap_msgfree(result); + return NT_STATUS_UNSUCCESSFUL; + } + + /* Check if we need to add an entry */ + DEBUG(3,("Adding new domain\n")); + ldap_op = LDAP_MOD_ADD; + + pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), + domain_name, lp_ldap_suffix()); + + /* Free original search */ + ldap_msgfree(result); + + /* make the changes - the entry *must* not already have samba attributes */ + smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), + domain_name); + + /* If we don't have an entry, then ask secrets.tdb for what it thinks. + It may choose to make it up */ + + sid_to_string(sid_string, get_global_sam_sid()); + smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), sid_string); + + slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string) - 1, "%i", algorithmic_rid_base()); + smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE), + algorithmic_rid_base_string); + smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO); + + /* add the sambaNext[User|Group]Rid attributes if the idmap ranges are set. + TODO: fix all the places where the line between idmap and normal operations + needed by smbd gets fuzzy --jerry 2003-08-11 */ + + if ( lp_idmap_uid(&u_low, &u_high) && lp_idmap_gid(&g_low, &g_high) + && get_free_rid_range(&rid_low, &rid_high) ) + { + fstring rid_str; + + fstr_sprintf( rid_str, "%i", rid_high|USER_RID_TYPE ); + DEBUG(10,("setting next available user rid [%s]\n", rid_str)); + smbldap_set_mod(&mods, LDAP_MOD_ADD, + get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), + rid_str); + + fstr_sprintf( rid_str, "%i", rid_high|GROUP_RID_TYPE ); + DEBUG(10,("setting next available group rid [%s]\n", rid_str)); + smbldap_set_mod(&mods, LDAP_MOD_ADD, + get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), + rid_str); + + } + + + switch(ldap_op) + { + case LDAP_MOD_ADD: + rc = smbldap_add(ldap_state, dn, mods); + break; + case LDAP_MOD_REPLACE: + rc = smbldap_modify(ldap_state, dn, mods); + break; + default: + DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op)); + return NT_STATUS_INVALID_PARAMETER; + } + + if (rc!=LDAP_SUCCESS) { + char *ld_error = NULL; + ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); + DEBUG(1,("failed to %s domain dn= %s with: %s\n\t%s\n", + ldap_op == LDAP_MOD_ADD ? "add" : "modify", + dn, ldap_err2string(rc), + ld_error?ld_error:"unknown")); + SAFE_FREE(ld_error); + + ldap_mods_free(mods, True); + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(2,("added: domain = %s in the LDAP database\n", domain_name)); + ldap_mods_free(mods, True); + return NT_STATUS_OK; +} + +/********************************************************************** +Search for the domain info entry +*********************************************************************/ +NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, + LDAPMessage ** result, const char *domain_name, + BOOL try_add) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + pstring filter; + int rc; + char **attr_list; + int count; + + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", + LDAP_OBJ_DOMINFO, + get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), + domain_name); + + DEBUG(2, ("Searching for:[%s]\n", filter)); + + + attr_list = get_attr_list( dominfo_attr_list ); + rc = smbldap_search_suffix(ldap_state, filter, attr_list , result); + free_attr_list( attr_list ); + + if (rc != LDAP_SUCCESS) { + DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc))); + DEBUG(2,("Query was: %s, %s\n", lp_ldap_suffix(), filter)); + } else if (ldap_count_entries(ldap_state->ldap_struct, *result) < 1) { + DEBUG(3, ("Got no domain info entries for domain\n")); + ldap_msgfree(*result); + *result = NULL; + if (try_add && NT_STATUS_IS_OK(ret = add_new_domain_info(ldap_state, domain_name))) { + return smbldap_search_domain_info(ldap_state, result, domain_name, False); + } + else { + DEBUG(0, ("Adding domain info for %s failed with %s\n", + domain_name, nt_errstr(ret))); + return ret; + } + } else if ((count = ldap_count_entries(ldap_state->ldap_struct, *result)) > 1) { + DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n", + count, domain_name)); + ldap_msgfree(*result); + *result = NULL; + return ret; + } else { + return NT_STATUS_OK; + } + + return ret; +} + diff --git a/source3/param/config_ldap.c b/source3/param/config_ldap.c new file mode 100644 index 0000000000..ad9b515381 --- /dev/null +++ b/source3/param/config_ldap.c @@ -0,0 +1,354 @@ +/* + Unix SMB/CIFS implementation. + + ModConfig LDAP backend + + Copyright (C) Simo Sorce 2003 + Copyright (C) Jim McDonough 2003 + Copyright (C) Gerald Carter 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/*#undef DBGC_CLASS +#define DBGC_CLASS DBGC_CONFIG +*/ + +#include +#include + +#include "smbldap.h" + +#define LDAP_OBJ_SAMBA_CONFIG "sambaConfig" +#define LDAP_OBJ_SAMBA_SHARE "sambaShare" +#define LDAP_OBJ_SAMBA_OPTION "sambaConfigOption" + +#define LDAP_ATTR_LIST_END 0 +#define LDAP_ATTR_BOOL 1 +#define LDAP_ATTR_INTEGER 2 +#define LDAP_ATTR_STRING 3 +#define LDAP_ATTR_LIST 4 +#define LDAP_ATTR_NAME 5 + + +struct ldap_config_state { + struct smbldap_state *smbldap_state; + TALLOC_CTX *mem_ctx; +}; + +ATTRIB_MAP_ENTRY option_attr_list[] = { + { LDAP_ATTR_NAME, "sambaOptionName" }, + { LDAP_ATTR_LIST, "sambaListOption" }, + { LDAP_ATTR_STRING, "sambaStringOption" }, + { LDAP_ATTR_INTEGER, "sambaIntegerOption" }, + { LDAP_ATTR_BOOL, "sambaBoolOption" }, + { LDAP_ATTR_LIST_END, NULL } +}; + +static struct ldap_config_state ldap_state; +static char *config_base_dn; + +static NTSTATUS ldap_config_close(void); + +/* +TODO: + search each section + start with global, then with others + for each section parse all options +*/ + +static NTSTATUS parse_section( + const char *dn, + BOOL (*pfunc)(const char *, const char *)) +{ + TALLOC_CTX *mem_ctx; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + LDAPMessage *result = NULL; + LDAPMessage *entry = NULL; + pstring filter; + pstring suffix; + pstring option_name; + pstring option_value; + char **attr_list = NULL; + char *temp; + int rc; + int count; + + mem_ctx = talloc_init("parse_section"); + + /* search for the options */ + pstr_sprintf(filter, "objectClass=%s", + LDAP_OBJ_SAMBA_OPTION); + + DEBUG(0, ("Searching for:[%s]\n", filter)); + + attr_list = get_attr_list(option_attr_list); + rc = smbldap_search(ldap_state.smbldap_state, + dn, LDAP_SCOPE_ONELEVEL, + filter, attr_list, 0, &result); + + if (rc != LDAP_SUCCESS) { + DEBUG(0,("parse_section: %s object not found\n", LDAP_OBJ_SAMBA_CONFIG)); + goto done; + } + + count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); + entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); + while (entry) { + int o; + + if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, "sambaOptionName", option_name)) { + goto done; + } + + option_value[0] = '\0'; + for (o = 1; option_attr_list[o].name != NULL; o++) { + if (smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, option_attr_list[o].name, option_value)) { + break; + } + } + if (option_value[0] != '\0') { + if (!pfunc(option_name, option_value)) { + goto done; + } + } else { + DEBUG(0,("parse_section: Missing value for option: %s\n", option_name)); + goto done; + } + + entry = ldap_next_entry(ldap_state.smbldap_state->ldap_struct, entry); + } + + ret = NT_STATUS_OK; + +done: + talloc_destroy(mem_ctx); + free_attr_list(attr_list); + if (result) ldap_msgfree(result); + + return ret; +} + +/***************************************************************************** + load configuration from ldap +*****************************************************************************/ + +static NTSTATUS ldap_config_load( + BOOL (*sfunc)(const char *), + BOOL (*pfunc)(const char *, const char *)) +{ + TALLOC_CTX *mem_ctx; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + LDAPMessage *result = NULL; + LDAPMessage *entry = NULL; + pstring filter; + pstring suffix; + pstring attr_text; + char *config_dn = NULL; + char *temp; + int rc; + int count; + char *config_attr_list[] = {"description", NULL}; + char *share_attr_list[] = {"sambaShareName", "description", NULL}; + char **share_dn; + char **share_name; + + mem_ctx = talloc_init("ldap_config_load"); + + /* search for the base config dn */ + pstr_sprintf(filter, "objectClass=%s", + LDAP_OBJ_SAMBA_CONFIG); + + DEBUG(0, ("Searching for:[%s]\n", filter)); + + rc = smbldap_search(ldap_state.smbldap_state, + config_base_dn, LDAP_SCOPE_SUBTREE, + filter, config_attr_list, 0, &result); + + if (rc != LDAP_SUCCESS) { + DEBUG(0,("ldap_config_load: %s object not found\n", LDAP_OBJ_SAMBA_CONFIG)); + goto done; + } + + count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); + if (count != 1) { + DEBUG(0,("ldap_config_load: single %s object not found\n", LDAP_OBJ_SAMBA_CONFIG)); + goto done; + } + + if (!(temp = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result))) { + goto done; + } + config_dn = talloc_strdup(mem_ctx, temp); + SAFE_FREE(temp); + if (!config_dn) { + goto done; + } + + entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); + + if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, "description", attr_text)) { + DEBUG(0, ("ldap_config_load: no description field in %s object\n", LDAP_OBJ_SAMBA_CONFIG)); + } + + if (result) ldap_msgfree(result); +/* TODO: finish up the last section, see loadparm's lp_load()*/ + + /* retrive the section list */ + pstr_sprintf(filter, "objectClass=%s", + LDAP_OBJ_SAMBA_SHARE); + + DEBUG(0, ("Searching for:[%s]\n", filter)); + + rc = smbldap_search(ldap_state.smbldap_state, + config_dn, LDAP_SCOPE_SUBTREE, + filter, share_attr_list, 0, &result); + + if (rc != LDAP_SUCCESS) { + DEBUG(0,("ldap_config_load: %s object not found\n", LDAP_OBJ_SAMBA_CONFIG)); + goto done; + } + + count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); + DEBUG(0, ("config_ldap: Found %d shares\n", count)); + if (count) { + int i; + + share_dn = talloc(mem_ctx, (count + 1) * sizeof(char *)); + share_name = talloc(mem_ctx, (count) * sizeof(char *)); + if (!share_dn || !share_name) { + DEBUG(0,("config_ldap: Out of memory!\n")); + goto done; + } + entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); + i = 0; + while (entry) { + if (!(temp = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, entry))) { + goto done; + } + if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, "sambaShareName", attr_text)) { + goto done; + } + share_dn[i] = talloc_strdup(mem_ctx, temp); + share_name[i] = talloc_strdup(mem_ctx, attr_text); + if (!share_dn[i] || !share_name[i]) { + DEBUG(0,("config_ldap: Out of memory!\n")); + goto done; + } + + DEBUG(0, ("config_ldap: Found share [%s] (%s)\n", attr_text, temp)); + SAFE_FREE(temp); + + entry = ldap_next_entry(ldap_state.smbldap_state->ldap_struct, entry); + i++; + if (entry && (count == i)) { + DEBUG(0, ("Error too many entryes in ldap result\n")); + goto done; + } + } + share_dn[i] = NULL; + } + + /* parse global section*/ + if (!sfunc("global")) { + goto done; + } + if (!NT_STATUS_IS_OK(parse_section(config_dn, pfunc))) { + goto done; + } else { /* parse shares */ + int i; + + for (i = 0; share_dn[i] != NULL; i++) { + if (!sfunc(share_name[i])) { + goto done; + } + if (!NT_STATUS_IS_OK(parse_section(share_dn[i], pfunc))) { + goto done; + } + } + } + +done: + talloc_destroy(mem_ctx); + if (result) ldap_msgfree(result); + + return ret; +} + +/***************************************************************************** + Initialise config_ldap module +*****************************************************************************/ + +static NTSTATUS ldap_config_init(char *params) +{ + NTSTATUS nt_status; + const char *location; + const char *basedn; + + ldap_state.mem_ctx = talloc_init("config_ldap"); + if (!ldap_state.mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + /* we assume only location is passed through an inline parameter + * other options go via parametrical options */ + if (params) { + location = params; + } else { + location = lp_parm_const_string(GLOBAL_SECTION_SNUM, "config_ldap", "url", "ldap://localhost"); + } + DEBUG(0,("config_ldap: location=%s\n", location)); + basedn = lp_parm_const_string(GLOBAL_SECTION_SNUM, "config_ldap", "basedn", NULL); + if (basedn) config_base_dn = smb_xstrdup(basedn); + + if (!NT_STATUS_IS_OK(nt_status = + smbldap_init(ldap_state.mem_ctx, location, + &ldap_state.smbldap_state))) { + talloc_destroy(ldap_state.mem_ctx); + DEBUG(0,("config_ldap: smbldap_init failed!\n")); + return nt_status; + } + + return NT_STATUS_OK; +} + +/***************************************************************************** + End the LDAP session +*****************************************************************************/ + +static NTSTATUS ldap_config_close(void) +{ + + smbldap_free_struct(&(ldap_state).smbldap_state); + talloc_destroy(ldap_state.mem_ctx); + + DEBUG(5,("The connection to the LDAP server was closed\n")); + /* maybe free the results here --metze */ + + return NT_STATUS_OK; +} + +static struct config_functions functions = { + ldap_config_init, + ldap_config_load, + ldap_config_close +}; + +NTSTATUS config_ldap_init(void) +{ + return smb_register_config(SAMBA_CONFIG_INTERFACE_VERSION, "ldap", &functions); +} diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 37644c738f..3aeb80b7f0 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -95,6 +95,7 @@ struct _param_opt_struct { */ typedef struct { + char *szConfigBackend; char *smb_ports; char *dos_charset; char *unix_charset; @@ -755,6 +756,7 @@ static const struct enum_list enum_map_to_guest[] = { static struct parm_struct parm_table[] = { {N_("Base Options"), P_SEP, P_SEPARATOR}, + {"config backend", P_STRING, P_GLOBAL, &Globals.szConfigBackend, NULL, NULL, FLAG_ADVANCED}, {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED}, {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED}, {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED}, @@ -1302,6 +1304,8 @@ static void init_globals(void) DEBUG(3, ("Initialising global parameters\n")); + string_set(&Globals.szConfigBackend, NULL); + string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE); string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR); @@ -1604,6 +1608,7 @@ static char *lp_string(const char *s) #define FN_LOCAL_INTEGER(fn_name,val) \ int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);} +FN_GLOBAL_STRING(lp_config_backend, &Globals.szConfigBackend) FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports) FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset) FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset) @@ -3952,6 +3957,11 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults, if (iServiceIndex >= 0) bRetval = service_ok(iServiceIndex); + if (lp_config_backend()) { + modconf_init(lp_config_backend()); + modconf_load(do_section, do_parameter); + } + lp_add_auto_services(lp_auto_services()); if (add_ipc) { diff --git a/source3/param/modconf.c b/source3/param/modconf.c new file mode 100644 index 0000000000..a9ab6f9b4a --- /dev/null +++ b/source3/param/modconf.c @@ -0,0 +1,96 @@ +/* + Unix SMB/CIFS implementation. + Configuration Modules Support + Copyright (C) Simo Sorce 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +struct modconf_struct { + char *name; + struct config_functions *fns; +}; + +static struct modconf_struct module; + +NTSTATUS smb_register_config(int version, const char *name, struct config_functions *fns) +{ + if ((version != SAMBA_CONFIG_INTERFACE_VERSION)) { + DEBUG(0, ("smb_register_config: Failed to register config module.\n" + "The module has been compiled with a different interface version (%d).\n" + "The supported version is: %d\n", + version, SAMBA_CONFIG_INTERFACE_VERSION)); + return NT_STATUS_OBJECT_TYPE_MISMATCH; + } + + if (!name || !name[0]) { + DEBUG(0,("smb_register_config: Name missing!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + module.name = smb_xstrdup(name); + module.fns = fns; + DEBUG(5, ("smb_register_config: Successfully registeres config backend '%s'\n", name)); + return NT_STATUS_OK; +} + +/********************************************************************** + * Init the configuration module + *********************************************************************/ + +BOOL modconf_init(const char *config_backend) +{ + NTSTATUS ret; + BOOL bret = False; + char *name; + char *params; + + /* nothing to do */ + if (!config_backend) + return True; + + name = smb_xstrdup(config_backend); + if ((params = strchr(name, ':')) != NULL ) { + *params = '\0'; + params++; + } + + ret = smb_probe_module("config", name); + + if (NT_STATUS_IS_OK(ret) && NT_STATUS_IS_OK(module.fns->init(params))) + bret = True; + + SAFE_FREE(name); + return bret; +} + +BOOL modconf_load(BOOL (*sfunc)(const char *),BOOL (*pfunc)(const char *, const char *)) +{ + if (module.fns) { + if (NT_STATUS_IS_OK(module.fns->load(sfunc, pfunc))) { + return True; + } + } + return False; +} + +NTSTATUS modconf_close(void) +{ + return module.fns->close(); +} -- cgit From c473b3983e068ef638fb43956076594fb0fac8fc Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 15 Nov 2003 00:52:06 +0000 Subject: add also the schema attributes and object classes need by config_ldap Jerry, if you have any problems with these schema additions, let me know, so that we can arrange the right solution (This used to be commit e17af6d6cf9244b1204f13b7d5be76b4595d5b95) --- examples/LDAP/samba.schema | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema index 14cd720588..79f5891651 100644 --- a/examples/LDAP/samba.schema +++ b/examples/LDAP/samba.schema @@ -288,6 +288,38 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' + DESC 'Share Name' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' + DESC 'Option Name' + EQUALITY caseIgnoreMatch + SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' + DESC 'A boolean option' + EQUALITY booleanMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' + DESC 'An integer option' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' + DESC 'A string option' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption' + DESC 'A string list option' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + ####################################################################### ## objectClasses used by Samba 3.0 schema ## ####################################################################### @@ -343,3 +375,19 @@ objectclass ( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL DESC 'Structural Class for a SID' MUST ( sambaSID ) ) + + + +objectclass ( 1.3.6.1.4.1.7165.1.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY + DESC 'Samba Configuration Section' + MAY ( description ) ) + +objectclass ( 1.3.6.1.4.1.7165.1.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL + DESC 'Samba Share Section' + MUST ( sambaShareName ) + MAY ( description ) ) + +objectclass ( 1.3.6.1.4.1.7165.1.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL + DESC 'Samba Configuration Option' + MUST ( sambaOptionName ) + MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringListoption $ description ) ) -- cgit From fca92574af0ec65745ae510b894e484fa154b606 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 16 Nov 2003 09:11:38 +0000 Subject: do not build config_ldap by default (forget to remove the module from the default list after testing :-) (This used to be commit aae13b2e63dd3aeafe7dcb48a484da9d51a0a589) --- source3/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index b8c8eeaaa0..64fd7bd168 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -300,7 +300,7 @@ dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_epmapper auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin pdb_gums gums_tdbsam2" dnl These are preferably build shared, and static if dlopen() is not available -default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap charset_CP850 charset_CP437 config_ldap" +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap charset_CP850 charset_CP437" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_echo" -- cgit From 2274603a86bfa0a91037a1fbaad3497c7083e2f4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 17 Nov 2003 14:16:55 +0000 Subject: updates from Buchan (This used to be commit f7e4ea27a330b84bc67c71c10a5c1fb009572fb2) --- packaging/Mandrake/samba2.spec.tmpl | 213 +++++++++++++++++++----------------- packaging/Mandrake/smb.conf | 29 +++-- 2 files changed, 134 insertions(+), 108 deletions(-) diff --git a/packaging/Mandrake/samba2.spec.tmpl b/packaging/Mandrake/samba2.spec.tmpl index 787ea1e5db..cff54d146b 100644 --- a/packaging/Mandrake/samba2.spec.tmpl +++ b/packaging/Mandrake/samba2.spec.tmpl @@ -13,8 +13,8 @@ # cvs should be submitted for inclusion in samba cvs. %define pkg_name samba -%define ver 3.0.0rc4 -%define rel 2mdk +%define ver 3.0.1pre3 +%define rel 3mdk %define vscanver 0.3.3beta1 %define libsmbmajor 0 @@ -58,6 +58,7 @@ # We now do detection of the Mandrake release we are building on: #%define build_cooker %(if [ `awk '{print $3}' /etc/mandrake-release` = "Cooker" ];then echo 1; else echo 0; fi) #%define build_cooker %(if [[ `cat /etc/mandrake-release|grep Cooker` ]];then echo 1; else echo 0; fi) +%define build_mdk100 %(if [ `awk '{print $4}' /etc/mandrake-release` = 10.0 ];then echo 1; else echo 0; fi) %define build_mdk92 %(if [ `awk '{print $4}' /etc/mandrake-release` = 9.2 ];then echo 1; else echo 0; fi) %define build_mdk91 %(if [ `awk '{print $4}' /etc/mandrake-release` = 9.1 ];then echo 1; else echo 0; fi) %define build_mdk90 %(if [ `awk '{print $4}' /etc/mandrake-release` = 9.0 ];then echo 1; else echo 0; fi) @@ -82,6 +83,12 @@ %define have_rpmhelper 1 # Set defaults for each version +%if %build_mdk100 +%define build_system 1 +%define build_alternatives 1 +%define build_cupspc 1 +%endif + %if %build_mdk92 %define build_alternatives 1 %define build_cupspc 1 @@ -182,7 +189,7 @@ #Standard texts for descriptions: %define message_bugzilla() %(echo -e -n "Please file bug reports for this package at Mandrake bugzilla \\n(http://qa.mandrakesoft.com) under the product name %{1}") -%define message_system %(echo -e -n "NOTE: This is a prerelease of samba-%{samba_major}, not intended for production\\n use. Rather these packages are provided, parallel installable\\nwith samba-2.2.x, for testing purposes") +%define message_system %(echo -e -n "NOTE: These packages of samba-%{version}, are provided, parallel installable\\nwith samba-2.2.x, to allow easy migration from samba-2.2.x to samba-%{version},\\nbut are not officially supported") #check gcc version to disable some optimisations on gcc-3.3.1 %define gcc331 %(gcc -dumpversion|awk '{if ($1>3.3) print 1; else print 0}') @@ -190,8 +197,8 @@ #Define sets of binaries that we can use in globs and loops: %global commonbin net,ntlm_auth,rpcclient,smbcacls,smbcquotas,smbpasswd,smbtree,testparm,testprns -%global serverbin editreg,pdbedit,profiles,smbcontrol,smbstatus,tdbbackup -%global serversbin nmbd,samba,smbd +%global serverbin editreg,pdbedit,profiles,smbcontrol,smbstatus,tdbbackup,tdbdump +%global serversbin nmbd,samba,smbd,mkntpwd %global clientbin findsmb,nmblookup,smbclient,smbmnt,smbmount,smbprint,smbspool,smbtar,smbumount %global client_bin mount.cifs @@ -257,13 +264,10 @@ Source7: README.%{name}-mandrake-rpm Source8: samba-vscan-%{vscanver}.tar.bz2 %endif Source10: samba-print-pdf.sh.bz2 -Source11: mount.cifs.8.bz2 Patch1: smbw.patch.bz2 -Patch3: samba-2.2.0-buildroot.patch.bz2 Patch4: samba-3.0-smbmount-sbin.patch.bz2 %if !%have_pversion # Version specific patches: current version -Patch100: samba-3.0.0rc4-mandrake-packaging.patch.bz2 %else # Version specific patches: upcoming version %endif @@ -485,6 +489,11 @@ URL: http://www.samba.org Summary: Samba-winbind daemon, utilities and documentation Group: System/Servers Requires: %{name}-common = %{version} +%endif +%if %build_winbind && !%build_system +Conflicts: samba-winbind +%endif +%if %build_winbind %description winbind Provides the winbind daemon and testing tools to allow authentication and group/user enumeration from a Windows or Samba domain controller. @@ -503,6 +512,11 @@ Summary: Name Service Switch service for WINS Group: System/Servers Requires: %{name}-common = %{version} PreReq: glibc +%endif +%if %build_wins && !%build_system +Conflicts: nss_wins +%endif +%if %build_wins %description -n nss_wins%{samba_major} Provides the libnss_wins shared library which resolves NetBIOS names to IP addresses. @@ -524,7 +538,8 @@ Requires: %{name}-common = %{version} %if %build_system && %{?_with_test:1}%{!?_with_test:0} Provides: samba3-test samba3-debug Obsoletes: samba3-test samba3-debug -%else +%endif +%if !%build_system && %{?_with_test:1}%{!?_with_test:0} Provides: samba-test samba3-debug Obsoletes: samba3-debug %endif @@ -606,23 +621,29 @@ allowing the development of other software to access SMB shares. URL: http://www.samba.org Summary: Samba password database plugin for MySQL Group: System/Libraries +Requires: %{name}-server = %{version}-%{release} +%endif +%ifnarch alpha && %build_system +Obsoletes: samba3-passdb-mysql +Provides: samba3-passdb-mysql +%endif +%ifnarch alpha %description passdb-mysql The passdb-mysql package for samba provides a password database backend allowing samba to store account details in a MySQL database %endif -%ifnarch alpha && %have_pversion -%message_bugzilla samba3-passdb-mysql -%endif -%ifnarch alpha && !%build_system -%message_system -%endif %package passdb-xml URL: http://www.samba.org Summary: Samba password database plugin for XML files Group: System/Libraries +Requires: %{name}-server = %{version}-%{release} +%if %build_system +Obsoletes: samba3-passdb-xml +Provides: samba3-passdb-xml +%endif %description passdb-xml The passdb-xml package for samba provides a password database @@ -791,12 +812,10 @@ echo -e "\n%{name}-%{version}-%{release}\n">>%{SOURCE7} %endif #%patch111 -p1 %patch1 -p1 -b .smbw -%patch3 -p1 -b .buildroot %patch4 -p1 -b .sbin # Version specific patches: current version %if !%have_pversion echo "Applying patches for current version: %{ver}" -%patch100 -p1 -b .mdk %else # Version specific patches: upcoming version echo "Applying patches for new versions: %{pversion}" @@ -989,7 +1008,7 @@ mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{name}/scripts #smbwrapper and pam_winbind not handled by make, pam_smbpass.so doesn't build #install -m 755 source/bin/smbwrapper.so $RPM_BUILD_ROOT%{_libdir}/smbwrapper%{samba_major}.so install -m 755 source/bin/pam_smbpass.so $RPM_BUILD_ROOT/%{_lib}/security/pam_smbpass%{samba_major}.so -install -m 755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/%{_lib}/security/pam_winbind%{samba_major}.so +install -m 755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/%{_lib}/security/pam_winbind.so install -m755 source/bin/libsmbclient.a $RPM_BUILD_ROOT%{_libdir}/libsmbclient.a pushd $RPM_BUILD_ROOT/%{_libdir} @@ -1021,10 +1040,10 @@ popd #libnss_* not handled by make: # Install the nsswitch library extension file for i in wins winbind; do - install -m755 source/nsswitch/libnss_${i}.so $RPM_BUILD_ROOT/%{_lib}/libnss_${i}%{samba_major}.so + install -m755 source/nsswitch/libnss_${i}.so $RPM_BUILD_ROOT/%{_lib}/libnss_${i}.so done # Make link for wins and winbind resolvers -( cd $RPM_BUILD_ROOT/%{_lib}; ln -s libnss_wins%{samba_major}.so libnss_wins%{samba_major}.so.2; ln -s libnss_winbind%{samba_major}.so libnss_winbind%{samba_major}.so.2) +( cd $RPM_BUILD_ROOT/%{_lib}; ln -s libnss_wins.so libnss_wins.so.2; ln -s libnss_winbind.so libnss_winbind.so.2) %if %{?_with_test:1}%{!?_with_test:0} for i in {%{testbin}};do @@ -1041,11 +1060,11 @@ done install -m755 packaging/Mandrake/findsmb $RPM_BUILD_ROOT/%{_bindir} install -m755 packaging/Mandrake/smb.init $RPM_BUILD_ROOT/%{_initrddir}/smb%{samba_major} install -m755 packaging/Mandrake/smb.init $RPM_BUILD_ROOT/%{_sbindir}/%{name} - install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/%{_initrddir}/winbind%{samba_major} + install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/%{_initrddir}/winbind # install -m755 packaging/Mandrake/wrepld.init $RPM_BUILD_ROOT/%{_initrddir}/wrepld%{samba_major} - install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/%{_sbindir}/winbind%{samba_major} + install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/%{_sbindir}/winbind install -m644 packaging/Mandrake/samba.pamd $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/%{name} - install -m644 packaging/Mandrake/system-auth-winbind.pamd $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/system-auth-winbind%{samba_major} + install -m644 packaging/Mandrake/system-auth-winbind.pamd $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/system-auth-winbind # install -m644 %{SOURCE1} $RPM_BUILD_ROOT/%{_sysconfdir}/logrotate.d/%{name} # install -m644 packaging/Mandrake/samba-slapd-include.conf $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/samba-slapd.include @@ -1069,6 +1088,7 @@ perl -pi -e 's/^(use|package)(\s+)smbldap_(\w+);$/${1}${2}smbldap_${3}%{samba_ma perl -pi -e 's,/usr/local/sbin/mkntpwd,/usr/sbin/mkntpwd%{samba_major},g;s,553,421,g' %{buildroot}/%{_sysconfdir}/%{name}/smbldap_conf.pm perl -pi -e 's,\$smbldap_conf::SID,\$smbldap_conf3::SID,g' %{buildroot}/%{_datadir}/%{name}/scripts/smbldap*.p? %endif +perl -pi -e 's,/usr/local/sbin/smbldap-passwd.pl,%{_datadir}/%{name}/scripts/smbldap-passwd.pl,g' %{buildroot}/%{_datadir}/%{name}/scripts/smbldap-useradd.pl # Link both smbldap*.pm into vendor-perl (any better ideas?) mkdir -p %{buildroot}/%{perl_vendorlib} @@ -1101,7 +1121,6 @@ perl -pi -e 's/printcap name = lpstat/printcap name = cups/g' $RPM_BUILD_ROOT/%{ #install mount.cifs install -m755 source/client/mount.cifs %{buildroot}/bin/mount.cifs%{samba_major} -#bzcat %{SOURCE11} > %{buildroot}/%{_mandir}/man8/mount.cifs%{samba_major}.8 echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/lmhosts @@ -1172,13 +1191,13 @@ done ) # Server/common binaries are versioned only if not system samba: %if !%build_system -for OLD in %{buildroot}/%{_bindir}/{%{commonbin}} %{buildroot}/%{_bindir}/{%{serverbin},wbinfo} %{buildroot}/%{_sbindir}/{%{serversbin},winbindd,swat} +for OLD in %{buildroot}/%{_bindir}/{%{commonbin}} %{buildroot}/%{_bindir}/{%{serverbin}} %{buildroot}/%{_sbindir}/{%{serversbin},swat} do NEW=`echo ${OLD}%{alternative_major}` mv $OLD $NEW -f ||: done # And the man pages too: -for OLD in %{buildroot}/%{_mandir}/man?/{%{commonbin},%{serverbin},wbinfo,%{serversbin},winbindd,swat,{%testbin},smb.conf,lmhosts}* +for OLD in %{buildroot}/%{_mandir}/man?/{%{commonbin},%{serverbin},%{serversbin},swat,{%testbin},smb.conf,lmhosts}* do if [ -e $OLD ] then @@ -1190,14 +1209,12 @@ do fi done # Replace paths in config files and init scripts: -for i in smb winbind;do +for i in smb ;do perl -pi -e 's,/subsys/'$i',/subsys/'$i'%{samba_major},g' $RPM_BUILD_ROOT/%{_initrddir}/${i}%{samba_major} done -for i in %{_sysconfdir}/%{name}/smb.conf %{_initrddir}/smb%{samba_major} %{_sbindir}/%{name} %{_initrddir}/winbind%{samba_major} %{_sbindir}/winbind%{samba_major} /%{_sysconfdir}/logrotate.d/%{name} /%{_sysconfdir}/xinetd.d/swat%{samba_major} %{_initrddir}/wrepld%{samba_major}; do - perl -pi -e 's,/%{pkg_name},/%{name},g; s,smbd,%{_sbindir}/smbd%{samba_major},g; s,nmbd,%{_sbindir}/nmbd%{samba_major},g; s,winbindd,%{_sbindir}/winbindd%{samba_major},g; s,/usr/sbin/swat,%{_sbindir}/swat%{samba_major},g;s,wrepld,%{_sbindir}/wrepld%{samba_major},g' $RPM_BUILD_ROOT/$i; +for i in %{_sysconfdir}/%{name}/smb.conf %{_initrddir}/smb%{samba_major} %{_sbindir}/%{name} %{_initrddir}/winbind /%{_sysconfdir}/logrotate.d/%{name} /%{_sysconfdir}/xinetd.d/swat%{samba_major} %{_initrddir}/wrepld%{samba_major}; do + perl -pi -e 's,/%{pkg_name},/%{name},g; s,smbd,%{_sbindir}/smbd%{samba_major},g; s,nmbd,%{_sbindir}/nmbd%{samba_major},g; s,/usr/sbin/swat,%{_sbindir}/swat%{samba_major},g;s,wrepld,%{_sbindir}/wrepld%{samba_major},g' $RPM_BUILD_ROOT/$i; done -# Fix pam files -perl -pi -e 's/winbind/winbind%{samba_major}/g' $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/system-auth-winbind%{samba_major} # Fix xinetd file for swat: perl -pi -e 's,/usr/sbin,%{_sbindir},g' $RPM_BUILD_ROOT/%{_sysconfdir}/xinetd.d/swat%{samba_major} %endif @@ -1228,17 +1245,6 @@ if [ -f $i ]; then fi done -# Remove the transient tdb files (modified from version in off. samba spec: -for TDB in brlock unexpected locking messages; do - if [ -e /var/cache/%{name}/$TDB.tdb ]; then - rm -f /var/cache/%{name}/$TDB.tdb; - fi; -done - -if [ -d /var/lock/samba ]; then - rm -rf /var/lock/samba -fi - %post common # Basic migration script for pre-2.2.1 users, # since smb config moved from /etc to %{_sysconfdir}/samba @@ -1257,12 +1263,6 @@ fi # Let's define the proper paths for config files perl -pi -e 's/(\/etc\/)(smb)/\1%{name}\/\2/' %{_sysconfdir}/%{name}/smb.conf -# Let's replace lpstat with cups in older smb.conf: -%if %build_cupspc -echo "Updating samba printing configuration if necessary..." -perl -pi -e 's/= lpstat/= cups/' %{_sysconfdir}/%{name}/smb.conf -%endif - # Fix the logrotate.d file from smb and nmb to smbd and nmbd if [ -f %{_sysconfdir}/logrotate.d/samba ]; then perl -pi -e 's/smb /smbd /' %{_sysconfdir}/logrotate.d/samba @@ -1275,14 +1275,14 @@ fi %if %build_winbind %post winbind if [ $1 = 1 ]; then - /sbin/chkconfig winbind%{samba_major} on + /sbin/chkconfig winbind on cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmsave cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmtemp for i in passwd group;do - grep ^$i %{_sysconfdir}/nsswitch.conf |grep -v 'winbind%{samba_major}' >/dev/null + grep ^$i %{_sysconfdir}/nsswitch.conf |grep -v 'winbind' >/dev/null if [ $? = 0 ];then - echo "Adding a winbind%{samba_major} entry to the $i section of %{_sysconfdir}/nsswitch.conf" - awk '/^'$i'/ {print $0 " winbind%{samba_major}"};!/^'$i'/ {print}' %{_sysconfdir}/nsswitch.conf.rpmtemp >%{_sysconfdir}/nsswitch.conf; + echo "Adding a winbind entry to the $i section of %{_sysconfdir}/nsswitch.conf" + awk '/^'$i'/ {print $0 " winbind"};!/^'$i'/ {print}' %{_sysconfdir}/nsswitch.conf.rpmtemp >%{_sysconfdir}/nsswitch.conf; cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmtemp else echo "$i entry found in %{_sysconfdir}/nsswitch.conf" @@ -1293,10 +1293,10 @@ fi %preun winbind if [ $1 = 0 ]; then - echo "Removing winbind%{samba_major} entries from %{_sysconfdir}/nsswitch.conf" - perl -pi -e 's/ winbind%{samba_major}//' %{_sysconfdir}/nsswitch.conf + echo "Removing winbind entries from %{_sysconfdir}/nsswitch.conf" + perl -pi -e 's/ winbind//' %{_sysconfdir}/nsswitch.conf - /sbin/chkconfig winbind%{samba_major} reset + /sbin/chkconfig winbind reset fi %endif %build_winbind @@ -1304,10 +1304,10 @@ fi %post -n nss_wins%{samba_major} if [ $1 = 1 ]; then cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmsave - grep '^hosts' %{_sysconfdir}/nsswitch.conf |grep -v 'wins%{samba_major}' >/dev/null + grep '^hosts' %{_sysconfdir}/nsswitch.conf |grep -v 'wins' >/dev/null if [ $? = 0 ];then echo "Adding a wins entry to the hosts section of %{_sysconfdir}/nsswitch.conf" - awk '/^hosts/ {print $0 " wins%{samba_major}"};!/^hosts/ {print}' %{_sysconfdir}/nsswitch.conf.rpmsave >%{_sysconfdir}/nsswitch.conf; + awk '/^hosts/ {print $0 " wins"};!/^hosts/ {print}' %{_sysconfdir}/nsswitch.conf.rpmsave >%{_sysconfdir}/nsswitch.conf; else echo "wins entry found in %{_sysconfdir}/nsswitch.conf" fi @@ -1318,7 +1318,7 @@ fi %preun -n nss_wins%{samba_major} if [ $1 = 0 ]; then echo "Removing wins entry from %{_sysconfdir}/nsswitch.conf" - perl -pi -e 's/ wins%{samba_major}//' %{_sysconfdir}/nsswitch.conf + perl -pi -e 's/ wins//' %{_sysconfdir}/nsswitch.conf #else # echo "Leaving %{_sysconfdir}/nsswitch.conf intact" fi @@ -1333,15 +1333,6 @@ if [ $1 = 0 ] ; then # /sbin/chkconfig --level 35 smb reset # Let's not loose /var/cache/samba -# for i in browse.dat wins.dat brlock.tdb unexpected.tdb connections.tdb \ -#locking.tdb messages.tdb;do -# if [ -e /var/cache/samba/$i ]; then -# mv -f /var/cache/samba/$i /var/cache/samba/$i.BAK -# fi; -# done - if [ -d /var/log/%{name} ]; then - rm -rf /var/log/%{name}/* - fi if [ -d /var/cache/%{name} ]; then mv -f /var/cache/%{name} /var/cache/%{name}.BAK fi @@ -1383,37 +1374,30 @@ echo -n " --slave ${i} ${j} ${i}%{alternative_major}";done) \ update-alternatives --auto smbclient %preun client -[ $1 = 0 ] && update-alternatives --remove smbclient %{_bindir}/smbclient%{alternative_major} +[ $1 = 0 ] && update-alternatives --remove smbclient %{_bindir}/smbclient%{alternative_major} ||: %endif -%triggerpostun -- samba < 1.9.18p7 - -if [ $1 != 0 ]; then - /sbin/chkconfig --level 35 smb on -fi - -%triggerpostun -- samba < 2.0.5a-3, samba >= 2.0.0 - -if [ $1 != 0 ]; then - [ ! -d /var/lock/samba ] && mkdir -m 0755 /var/lock/samba ||: - [ ! -d /var/spool/samba ] && mkdir -m 1777 /var/spool/samba ||: - [ -f %{_sysconfdir}/inetd.conf ] && chmod 644 %{_sysconfdir}/services %{_sysconfdir}/inetd.conf ||: -fi +%if %build_alternatives +%triggerpostun client -- samba-client, samba2-client +[ ! -e %{_bindir}/smbclient ] && update-alternatives --auto smbclient || : +%endif %files server %defattr(-,root,root) #%attr(-,root,root) /sbin/* -%{_sbindir}/%{name} -%{_sbindir}/smbd%{samba_major} -%{_sbindir}/nmbd%{samba_major} +%(for i in %{_sbindir}/{%{serversbin}}%{samba_major};do echo $i;done) +#%{_sbindir}/%{name} +#%{_sbindir}/smbd%{samba_major} +#%{_sbindir}/nmbd%{samba_major} +#%{_sbindir}/mkntpwd%{samba_major} #%{_sbindir}/wrepld%{samba_major} -%{_bindir}/smbcontrol%{samba_major} -%{_sbindir}/mkntpwd%{samba_major} -%{_bindir}/smbstatus%{samba_major} -%{_bindir}/pdbedit%{samba_major} -%{_bindir}/tdbbackup%{samba_major} -%{_bindir}/profiles%{samba_major} -%{_bindir}/editreg%{samba_major} +%(for i in %{_bindir}/{%{serverbin}}%{samba_major};do echo $i;done) +#%{_bindir}/smbcontrol%{samba_major} +#%{_bindir}/smbstatus%{samba_major} +#%{_bindir}/pdbedit%{samba_major} +#%{_bindir}/tdbbackup%{samba_major} +#%{_bindir}/profiles%{samba_major} +#%{_bindir}/editreg%{samba_major} %attr(755,root,root) /%{_lib}/security/pam_smbpass* %dir %{_libdir}/%{name}/vfs %{_libdir}/%{name}/vfs/*.so @@ -1438,7 +1422,7 @@ fi %attr(775,root,adm) %dir %{_localstatedir}/%{name}/netlogon %attr(755,root,root) %dir %{_localstatedir}/%{name}/profiles %attr(755,root,root) %dir %{_localstatedir}/%{name}/printers -%attr(775,root,adm) %dir %{_localstatedir}/%{name}/printers/* +%attr(2775,root,adm) %dir %{_localstatedir}/%{name}/printers/* %attr(1777,root,root) %dir /var/spool/%{name} %dir %{_datadir}/%{name} %dir %{_datadir}/%{name}/scripts @@ -1476,6 +1460,14 @@ fi %lang(ja) %{_datadir}/swat%{samba_major}/lang/ja %lang(tr) %{_datadir}/swat%{samba_major}/lang/tr %{_mandir}/man8/swat*.8* +%lang(de) %{_libdir}/%{name}/de.msg +%lang(en) %{_libdir}/%{name}/en.msg +%lang(fr) %{_libdir}/%{name}/fr.msg +%lang(it) %{_libdir}/%{name}/it.msg +%lang(ja) %{_libdir}/%{name}/ja.msg +%lang(nl) %{_libdir}/%{name}/nl.msg +%lang(pl) %{_libdir}/%{name}/pl.msg +%lang(tr) %{_libdir}/%{name}/tr.msg #%doc swat/README %files client @@ -1520,18 +1512,18 @@ fi %attr(-,root,root) %{_localstatedir}/%{name}/codepages %{_mandir}/man5/smb.conf*.5* %{_mandir}/man5/lmhosts*.5* -%{_mandir}/man7/Samba*.7* +#%{_mandir}/man7/Samba*.7* %dir %{_datadir}/swat%{samba_major} %if %build_winbind %files winbind %defattr(-,root,root) -%{_sbindir}/winbindd%{samba_major} -%{_sbindir}/winbind%{samba_major} -%{_bindir}/wbinfo%{samba_major} +%{_sbindir}/winbindd +%{_sbindir}/winbind +%{_bindir}/wbinfo %attr(755,root,root) /%{_lib}/security/pam_winbind* -%attr(755,root,root) /%{_lib}/libnss_winbind%{samba_major}* -%attr(-,root,root) %config(noreplace) %{_initrddir}/winbind%{samba_major} +%attr(755,root,root) /%{_lib}/libnss_winbind* +%attr(-,root,root) %config(noreplace) %{_initrddir}/winbind %attr(-,root,root) %config(noreplace) %{_sysconfdir}/pam.d/system-auth-winbind* %{_mandir}/man8/winbindd*.8* %{_mandir}/man1/wbinfo*.1* @@ -1540,7 +1532,7 @@ fi %if %build_wins %files -n nss_wins%{samba_major} %defattr(-,root,root) -%attr(755,root,root) /%{_lib}/libnss_wins%{samba_major}.so* +%attr(755,root,root) /%{_lib}/libnss_wins.so* %endif %if %{?_with_test:1}%{!?_with_test:0} @@ -1655,6 +1647,29 @@ fi %exclude %{_mandir}/man1/smbsh*.1* %changelog +* Sun Nov 16 2003 Buchan Milne 3.0.1-0.rpe3.3mdk +- Ensure printer drivers keep permissions by default (setgid and inherit perms) + +* Fri Nov 14 2003 Buchan Milne 3.0.1-0.pre3.2mdk +- 3.0.1pre3 +- Add support for Mandrake 10.0 (as system samba) +- Fix alternatives triggers +- Fix obsoletes + +* Mon Nov 10 2003 Buchan Milne 3.0.1-0.pre2.2mdk +- 3.0.1pre2 +- misc spec files (pointed out by Luca Olivetti) +- Fix path to smbldap-passwd.pl +- Only allow one copy of winbind and nss_wins +- Add trigger for alternatives + +* Sun Oct 12 2003 Buchan Milne 3.0.1-0.pre1.2mdk +- 3.0.1pre1 +- remove buildroot patch (p3), fixed upstream + +* Thu Sep 25 2003 Buchan Milne 3.0.0-2mdk +- 3.0.0 final + * Sat Sep 13 2003 Buchan Milne 3.0.0-0.rc4.2mdk - rc4 - Don't update alternatives in pre/post scripts when not using alternatives diff --git a/packaging/Mandrake/smb.conf b/packaging/Mandrake/smb.conf index 4981d22174..6c1c05fa52 100644 --- a/packaging/Mandrake/smb.conf +++ b/packaging/Mandrake/smb.conf @@ -263,7 +263,10 @@ # Use the samba2 LDAP schema: ; passdb backend = ldapsam_compat:ldaps://ldap.mydomain.com smbpasswd guest -# idmap uid account range: +# Idmap settings: +# Idmap backend to use: +; idmap backend = ldap:ldap://ldap.mydomain.com + # This is a range of unix user-id's that samba will map non-unix RIDs to, # such as when using Winbind ; idmap uid = 10000-20000 @@ -388,10 +391,13 @@ # NOTE: If you have a CUPS print system there is no need to # specifically define each individual printer. # You must configure the samba printers with the appropriate Windows -# drivers on your Windows clients. On the Samba server no filtering is +# drivers on your Windows clients or upload the printer driver to the +# server from Windows (NT/2000/XP). On the Samba server no filtering is # done. If you wish that the server provides the driver and the clients # send PostScript ("Generic PostScript Printer" under Windows), you have -# to swap the 'print command' line below with the commented one. +# to use 'printcap name = cups' or swap the 'print command' line below +# with the commented one. Note that print commands only work if not using +# 'printing=cups' [printers] comment = All Printers path = /var/spool/samba @@ -406,10 +412,6 @@ # ===================================== print command = lpr-cups -P %p -o raw %s -r # using client side printer drivers. ; print command = lpr-cups -P %p %s # using cups own drivers (use generic PostScript on clients). -# The following two commands are the samba defaults for printing=cups -# change them only if you need different options: -; lpq command = lpq -P %p -; lprm command = cancel %p-%j # This share is used for Windows NT-style point-and-print support. # To be able to install drivers, you need to be either root, or listed @@ -417,17 +419,26 @@ # to the directory and share definition to be able to upload the drivers. # For more information on this, please see the Printing Support Section of # /usr/share/doc/samba-/docs/Samba-HOWTO-Collection.pdf +# +# A special case is using the CUPS Windows Postscript driver, which allows +# all features available via CUPS on the client, by publishing the ppd file +# and the cups driver by using the 'cupsaddsmb' tool. This requires the +# installation of the CUPS driver (http://www.cups.org/windows.php) +# on the server, but doesn't require you to use Windows at all :-). [print$] path = /var/lib/samba/printers browseable = yes - read only = yes write list = @adm root guest ok = yes + inherit permissions = yes + # Settings suitable for Winbind: + ; write list = @"Domain Admins" root + ; force group = +@"Domain Admins" # A useful application of samba is to make a PDF-generation service # To streamline this, install windows postscript drivers (preferably colour) # on the samba server, so that clients can automatically install them. -# Note that this only works if 'printcap name' is *not* set to 'cups' +# Note that this only works if 'printing' is *not* set to 'cups' [pdf-generator] path = /var/tmp -- cgit From 8b9622f50de1f46c5e6870466a5ef8a37bf08df1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 17 Nov 2003 16:11:16 +0000 Subject: * make sure we only enumerate group mapping entries (not /etc/group) even when doing local aliases * remove "hide local users" parameter; we have this behavior built into 3.0 (This used to be commit 3b75e862dfba42c95e2279c300c06bb981f52993) --- source3/param/loadparm.c | 3 - source3/passdb/passdb.c | 14 --- source3/rpc_server/srv_samr_nt.c | 179 ++++++++++----------------------------- 3 files changed, 44 insertions(+), 152 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 3aeb80b7f0..2fb53100f3 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -282,7 +282,6 @@ typedef struct BOOL bDebugPid; BOOL bDebugUid; BOOL bHostMSDfs; - BOOL bHideLocalUsers; BOOL bUnicode; BOOL bUseMmap; BOOL bHostnameLookups; @@ -1137,7 +1136,6 @@ static struct parm_struct parm_table[] = { {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED}, - {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED}, {N_("VFS module options"), P_SEP, P_SEPARATOR}, @@ -1903,7 +1901,6 @@ FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize) FN_LOCAL_INTEGER(lp_block_size, iBlock_size) FN_LOCAL_CHAR(lp_magicchar, magic_char) FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time) -FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers) FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase) FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout) FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 48f7546394..7ac8d12198 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -725,14 +725,6 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use return True; } - /* - * Don't try to convert the rid to a name if - * running in appliance mode - */ - - if (lp_hide_local_users()) - return False; - if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) { return False; } @@ -852,12 +844,6 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi return True; } - /* - * Don't lookup local unix users if running in appliance mode - */ - if (lp_hide_local_users()) - return False; - (void)map_username(user); if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) { diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index b3e6478c88..1cfa8b2853 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -875,140 +875,11 @@ static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNIST /******************************************************************* Get the group entries - similar to get_sampwd_entries(). - ********************************************************************/ - -static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx, - uint32 *p_num_entries, uint32 max_entries) -{ - fstring sid_str; - uint32 num_entries = 0; - int i; - GROUP_MAP smap; - GROUP_MAP *map = NULL; - - sid_to_string(sid_str, sid); - DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str)); - - *p_num_entries = 0; - - /* well-known aliases */ - if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) { - - become_root(); - pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED); - unbecome_root(); - - if (num_entries != 0) { - *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP)); - if (*d_grp==NULL) - return NT_STATUS_NO_MEMORY; - - for(i=0; inext) { - uint32 trid; - - become_root(); - ret = pdb_getgrgid(&smap, grp->gr_gid); - unbecome_root(); - if( !ret ) - continue; - - if (smap.sid_name_use!=SID_NAME_ALIAS) { - continue; - } - - sid_split_rid(&smap.sid, &trid); - - if (!sid_equal(sid, &smap.sid)) - continue; - - /* Don't return winbind groups as they are not local! */ - if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) { - DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name )); - continue; - } - - /* Don't return user private groups... */ - - if (Get_Pwnam(smap.nt_name) != 0) { - DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name )); - continue; - } - - for( i = 0; i < num_entries; i++) - if ( (*d_grp)[i].rid == trid ) - break; - - if ( i < num_entries ) { - continue; /* rid was there, dup! */ - } - - /* JRA - added this for large group db enumeration... */ - - if (start_idx > 0) { - /* skip the requested number of entries. - not very efficient, but hey... - */ - start_idx--; - continue; - } - - *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP)); - if (*d_grp==NULL) { - grent_free(glist); - return NT_STATUS_NO_MEMORY; - } - - fstrcpy((*d_grp)[num_entries].name, smap.nt_name); - (*d_grp)[num_entries].rid = trid; - num_entries++; - DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid)); - } - - grent_free(glist); - } - - *p_num_entries = num_entries; - - DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries)); - - if (num_entries >= max_entries) - return STATUS_MORE_ENTRIES; - return NT_STATUS_OK; -} - -/******************************************************************* - Get the group entries - similar to get_sampwd_entries(). - ********************************************************************/ + ******************************************************************/ -static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx, - uint32 *p_num_entries, uint32 max_entries) +static NTSTATUS get_group_entries( enum SID_NAME_USE type, TALLOC_CTX *ctx, + DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx, + uint32 *p_num_entries, uint32 max_entries ) { GROUP_MAP *map=NULL; int i; @@ -1021,7 +892,7 @@ static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DO needed for some passdb backends to enumerate groups */ become_root(); - pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED); + pdb_enum_group_mapping(type, &map, (int *)&group_entries, ENUM_ONLY_MAPPED); unbecome_root(); num_entries=group_entries-start_idx; @@ -1042,13 +913,51 @@ static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DO fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name); fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment); sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid); - (*d_grp)[i].attr=SID_NAME_DOM_GRP; + (*d_grp)[i].attr=type; } SAFE_FREE(map); *p_num_entries = num_entries; + DEBUG(10,("get_group_entries: returning %d entries\n", *p_num_entries)); + + return NT_STATUS_OK; +} + +/******************************************************************* + Wrapper for enuemrating domain groups + ******************************************************************/ + +static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, + DOM_SID *sid, uint32 start_idx, + uint32 *p_num_entries, uint32 max_entries ) +{ + return get_group_entries( SID_NAME_DOM_GRP, ctx, d_grp, sid, start_idx, + p_num_entries, max_entries ); +} + +/******************************************************************* + Wrapper for enumerating local groups + ******************************************************************/ + +static NTSTATUS get_group_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, + DOM_SID *sid, uint32 start_idx, + uint32 *p_num_entries, uint32 max_entries) +{ + if ( sid_equal(sid, &global_sid_Builtin) ) { + return get_group_entries( SID_NAME_WKN_GRP, ctx, d_grp, + sid, start_idx, p_num_entries, max_entries ); + } + else if ( sid_equal(sid, get_global_sam_sid()) ) { + return get_group_entries( SID_NAME_ALIAS, ctx, d_grp, + sid, start_idx, p_num_entries, max_entries ); + } + + /* can't do anything with this SID */ + + *p_num_entries = 0; + return NT_STATUS_OK; } -- cgit From bfbc3486045f819a3e7ac9c7460a8793d5a1f0e5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 17 Nov 2003 18:01:28 +0000 Subject: From 3_0: This fixes a bug when establishing trust against a german W2k3 AD server. In the bind response to WKSSVC it does not send \PIPE\ntsvcs as NT4 (did not check w2k) but \PIPE\wkssvc. I'm not sure whether we should make this check at all, so making it a bit more liberal should hopefully not really hurt. Volker (This used to be commit dbd17dd0366d6cd20a2d5d8247dd5842563da2ca) --- source3/rpc_client/cli_pipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9ce10202db..fdd9d3c3b1 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1231,7 +1231,8 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC if ( hdr_ba->addr.len <= 0) return False; - if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe )) + if ( (strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) != 0) && + (strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) != 0) ) { DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n", pipe_names[i].server_pipe ,hdr_ba->addr.str)); -- cgit From c86a6b04c8fc279548f3a2a8fe638450c72e15c5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Nov 2003 22:07:23 +0000 Subject: Fix from Andrew Bartlett to fix up the munged-dial problem. Jeremy. (This used to be commit 5df3d16c9226bf884226e8302b996a484017f8c3) --- source3/rpc_parse/parse_misc.c | 6 +++++- source3/rpc_parse/parse_samr.c | 16 +++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index cd59d390aa..7cd3c795e6 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -1043,7 +1043,11 @@ void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) str->uni_str_len = blob->length / sizeof(uint16); str->uni_max_len = str->uni_str_len; str->offset = 0; - str->buffer = (uint16 *) memdup(blob->data, blob->length); + if (blob->length) { + str->buffer = (uint16 *) memdup(blob->data, blob->length); + } else { + str->buffer = NULL; + } if ((str->buffer == NULL) && (blob->length > 0)) { smb_panic("init_unistr2_from_datablob: malloc fail\n"); } diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 73107f8f61..20adf0c756 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -5938,7 +5938,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * const char* description = pdb_get_acct_desc(pw); const char* workstations = pdb_get_workstations(pw); const char* munged_dial = pdb_get_munged_dial(pw); - DATA_BLOB blob = base64_decode_data_blob(munged_dial); + DATA_BLOB munged_dial_blob; uint32 user_rid; const DOM_SID *user_sid; @@ -5946,6 +5946,12 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * uint32 group_rid; const DOM_SID *group_sid; + if (munged_dial) { + munged_dial_blob = base64_decode_data_blob(munged_dial); + } else { + munged_dial_blob = data_blob(NULL, 0); + } + /* Create NTTIME structs */ unix_to_nt_time (&logon_time, pdb_get_logon_time(pw)); unix_to_nt_time (&logoff_time, pdb_get_logoff_time(pw)); @@ -5975,7 +5981,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * user_name, sid_to_string(user_sid_string, user_sid), sid_to_string(domain_sid_string, domain_sid))); - data_blob_free(&blob); + data_blob_free(&munged_dial_blob); return NT_STATUS_UNSUCCESSFUL; } @@ -5989,7 +5995,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * user_name, sid_to_string(group_sid_string, group_sid), sid_to_string(domain_sid_string, domain_sid))); - data_blob_free(&blob); + data_blob_free(&munged_dial_blob); return NT_STATUS_UNSUCCESSFUL; } @@ -6049,9 +6055,9 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * init_unistr2(&usr->uni_unknown_str, NULL, UNI_STR_TERMINATE); init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str); - init_unistr2_from_datablob(&usr->uni_munged_dial, &blob); + init_unistr2_from_datablob(&usr->uni_munged_dial, &munged_dial_blob); init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial); - data_blob_free(&blob); + data_blob_free(&munged_dial_blob); usr->unknown_6 = pdb_get_unknown_6(pw); usr->padding4 = 0; -- cgit From 5e9265c997fef8193345bf3a4cad2bf19796ed01 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Nov 2003 01:47:15 +0000 Subject: Ensure we mangle names ending in '.' in hash2 mangling method. Jeremy. (This used to be commit 9b50fd8cfc36c817177103b07e7b8a3952e641c7) --- source3/smbd/mangle_hash2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c index 7e7bc8c68c..8dfa84d054 100644 --- a/source3/smbd/mangle_hash2.c +++ b/source3/smbd/mangle_hash2.c @@ -325,7 +325,7 @@ static BOOL is_8_3(const char *name, BOOL check_case, BOOL allow_wildcards) prefix_len = PTR_DIFF(dot_p, name); suffix_len = len - (prefix_len+1); - if (prefix_len > 8 || suffix_len > 3) { + if (prefix_len > 8 || suffix_len > 3 || suffix_len == 0) { return False; } -- cgit From 1276bbf4c9092ce8eaf3f0e30a85e71b8c0114b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Nov 2003 02:06:46 +0000 Subject: Remove unneeded second open for filename ending in '.' now we know it's a mangled name. Added const. Fix inspired by Andrew Bartlett ideas. Jeremy. (This used to be commit 8de1d4ebf72928c958d4c5be887f2babe13d3c87) --- source3/lib/util.c | 2 +- source3/smbd/open.c | 16 +++------------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/source3/lib/util.c b/source3/lib/util.c index ce1389c8e9..39515c6599 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2234,7 +2234,7 @@ char *parent_dirname(const char *path) Determine if a pattern contains any Microsoft wildcard characters. *******************************************************************/ -BOOL ms_has_wild(char *s) +BOOL ms_has_wild(const char *s) { char c; while ((c = *s++)) { diff --git a/source3/smbd/open.c b/source3/smbd/open.c index ef7ace862a..3807c18e78 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -30,7 +30,7 @@ extern BOOL global_client_failed_oplock_break; fd support routines - attempt to do a dos_open. ****************************************************************************/ -static int fd_open(struct connection_struct *conn, char *fname, +static int fd_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode) { int fd; @@ -41,13 +41,6 @@ static int fd_open(struct connection_struct *conn, char *fname, fd = SMB_VFS_OPEN(conn,fname,flags,mode); - /* Fix for files ending in '.' */ - if((fd == -1) && (errno == ENOENT) && - (strchr_m(fname,'.')==NULL)) { - pstrcat(fname,"."); - fd = SMB_VFS_OPEN(conn,fname,flags,mode); - } - DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname, flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" )); @@ -70,7 +63,7 @@ int fd_close(struct connection_struct *conn, files_struct *fsp) Check a filename for the pipe string. ****************************************************************************/ -static void check_for_pipe(char *fname) +static void check_for_pipe(const char *fname) { /* special case of pipe opens */ char s[10]; @@ -89,10 +82,9 @@ static void check_for_pipe(char *fname) ****************************************************************************/ static BOOL open_file(files_struct *fsp,connection_struct *conn, - const char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access) + const char *fname,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access) { extern struct current_user current_user; - pstring fname; int accmode = (flags & O_ACCMODE); int local_flags = flags; @@ -100,8 +92,6 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, fsp->oplock_type = NO_OPLOCK; errno = EPERM; - pstrcpy(fname,fname1); - /* Check permissions */ /* -- cgit From 8f78f1bed2d0a0fb007492d48ea84b18c31ca388 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 18 Nov 2003 19:39:51 +0000 Subject: Useful debug message. Patch by metze. rafal (This used to be commit 5f02adbd261b7fde22b72703135dec44b7652ef1) --- source3/lib/util_str.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index b6025a362d..5811b3b5e3 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -695,9 +695,11 @@ char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n) clobber_region(fn, line, dest, n+1); #endif - if (!dest) - return(NULL); - + if (!dest) { + DEBUG(0,("ERROR: NULL dest in StrnCpy\n")); + return NULL; + } + if (!src) { *dest = 0; return(dest); -- cgit From 66603d58e0328933ffb77ba160600b5af353cbd8 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 18 Nov 2003 20:06:10 +0000 Subject: Fix to correct checking of '$' name termination. Patch by metze. rafal (This used to be commit 7191186fc64eb0b8092a2f6f1e89b6b6a6df7627) --- source3/rpc_server/srv_srvsvc_nt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 4d1cf9bddc..1c57af0acf 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -490,7 +490,7 @@ static BOOL is_hidden_share(int snum) pstring net_name; pstrcpy(net_name, lp_servicename(snum)); - return (net_name[strlen(net_name)] == '$') ? True : False; + return (net_name[strlen(net_name) - 1] == '$') ? True : False; } /******************************************************************* -- cgit From 3848849b021bc39c31144a61b8aa210e00b39a13 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 Nov 2003 00:22:47 +0000 Subject: Correct fix for '$' termination test. Jeremy. (This used to be commit b93e44e01edb432e11b9ad6aeb4d4eea0f7fa433) --- source3/rpc_server/srv_srvsvc_nt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 1c57af0acf..40d3a43bef 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -487,9 +487,8 @@ static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh150 static BOOL is_hidden_share(int snum) { - pstring net_name; + const char *net_name = lp_servicename(snum); - pstrcpy(net_name, lp_servicename(snum)); return (net_name[strlen(net_name) - 1] == '$') ? True : False; } -- cgit From 1e6f7172dd3e019ad79bc2d86614b87386d98009 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 Nov 2003 02:19:33 +0000 Subject: Group quotas patch from "Heinreichsberger, Helmut" Jeremy. (This used to be commit 0984b35fbfd0c9579d2a8a6fa748ade604ad6a82) --- source3/smbd/quotas.c | 51 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c index 91c952aa90..46f688a219 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -94,23 +94,30 @@ typedef struct _LINUX_SMB_DISK_QUOTA { static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp) { - int ret = -1; + int ret = -1; #ifdef HAVE_LINUX_XQM_H - struct fs_disk_quota D; - ZERO_STRUCT(D); - - if ((ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D))) - return ret; - - dp->bsize = (SMB_BIG_UINT)512; - dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit; - dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit; - dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit; - dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit; - dp->curinodes = (SMB_BIG_UINT)D.d_icount; - dp->curblocks = (SMB_BIG_UINT)D.d_bcount; + struct fs_disk_quota D; + + ZERO_STRUCT(D); + + ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); + + /* As XFS has group quotas, if getting the user quota fails, try getting the group instead. */ + if (ret) { + ret = quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), path, getegid(), (caddr_t)&D); + if (ret) + return ret; + } + + dp->bsize = (SMB_BIG_UINT)512; + dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit; + dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit; + dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit; + dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit; + dp->curinodes = (SMB_BIG_UINT)D.d_icount; + dp->curblocks = (SMB_BIG_UINT)D.d_bcount; #endif - return ret; + return ret; } /**************************************************************************** @@ -119,7 +126,7 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp) { - int ret; + int ret = 0; #ifdef LINUX_QUOTAS_1 struct dqblk D; ZERO_STRUCT(D); @@ -133,8 +140,14 @@ static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; #endif - if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D))) - return -1; + ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); + + /* Linux can have group quotas, if getting the user quota fails, try getting the group instead. */ + if (ret) { + ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, getegid(), (caddr_t)&D); + if (ret) + return ret; + } dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; @@ -148,7 +161,7 @@ static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace)/ dp->bsize; #endif - return 0; + return ret; } /**************************************************************************** -- cgit From f5e68bcfa1145d45e04012a8acfb6104c86d61ce Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 Nov 2003 22:57:53 +0000 Subject: Look at error before using it in debug statement. Jeremy. (This used to be commit 42114b75f2c082522f7806a1af11409609785b06) --- source3/lib/module.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source3/lib/module.c b/source3/lib/module.c index 38fcf0f329..2abe918ef4 100644 --- a/source3/lib/module.c +++ b/source3/lib/module.c @@ -42,9 +42,8 @@ static NTSTATUS do_smb_load_module(const char *module_name, BOOL is_probe) if(!handle) { int level = is_probe ? 3 : 0; - DEBUG(level, ("Error loading module '%s': %s\n", module_name, - sys_dlerror())); - + error = sys_dlerror(); + DEBUG(level, ("Error loading module '%s': %s\n", module_name, error ? error : "")); return NT_STATUS_UNSUCCESSFUL; } -- cgit From 2a22bd3038c8b47834406d2bdb3457aea5fb9a11 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 19 Nov 2003 23:14:21 +0000 Subject: Added useful information to debug lines. Patch by metze. rafal (This used to be commit 91e1be66b1a3aa002f68d8f1c2fc148c1374d365) --- source3/lib/util_str.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 5811b3b5e3..aa50b07f61 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -574,7 +574,7 @@ char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_ size_t len; if (!dest) { - DEBUG(0,("ERROR: NULL dest in safe_strcpy\n")); + DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line)); return NULL; } @@ -610,7 +610,7 @@ char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size size_t src_len, dest_len; if (!dest) { - DEBUG(0,("ERROR: NULL dest in safe_strcat\n")); + DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line)); return NULL; } @@ -654,7 +654,7 @@ char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, con #endif if (!dest) { - DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n")); + DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line)); return NULL; } @@ -696,7 +696,7 @@ char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n) #endif if (!dest) { - DEBUG(0,("ERROR: NULL dest in StrnCpy\n")); + DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line)); return NULL; } -- cgit From ad88390a400b0506735fd99a92d96bef29dd5c06 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Thu, 20 Nov 2003 23:54:13 +0000 Subject: Typo fix. (This used to be commit d1394f02cb0e369701217ce6610f4efe54438c3a) --- source3/include/passdb.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 8d40bbfd26..be1f236e39 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -98,7 +98,7 @@ typedef struct sam_passwd struct pdb_methods *methods; struct user_data { - /* initiailization flags */ + /* initialization flags */ struct bitmap *change_flags; struct bitmap *set_flags; @@ -161,7 +161,7 @@ typedef struct sam_group { struct pdb_methods *methods; struct group_data { - /* initiailization flags */ + /* initialization flags */ struct bitmap *change_flags; struct bitmap *set_flags; -- cgit From 579cafe7449565f8893c82371910856020199a9b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 21 Nov 2003 19:12:33 +0000 Subject: make sure we don't append the ldap suffix when writing out the ldap XXX suffix values in SWAT; based on tpot's original patch; bug 328 (This used to be commit b1d5173b16c40d55cfb6265f1d1947ec78952b6f) --- source3/param/loadparm.c | 99 ++++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 2fb53100f3..6f2b798720 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -566,9 +566,6 @@ static BOOL handle_netbios_aliases( const char *pszParmValue, char **ptr ); static BOOL handle_netbios_scope( const char *pszParmValue, char **ptr ); static BOOL handle_charset( const char *pszParmValue, char **ptr ); -static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr ); -static BOOL handle_ldap_sub_suffix ( const char *pszParmValue, char **ptr ); - static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr); static void set_server_role(void); @@ -1067,11 +1064,11 @@ static struct parm_struct parm_table[] = { {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, FLAG_ADVANCED}, {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, FLAG_ADVANCED}, #endif - {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED}, - {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, - {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, - {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, - {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, + {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED}, + {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED}, + {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED}, + {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED}, + {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED}, {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED}, {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED}, {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED}, @@ -1696,10 +1693,6 @@ FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer) FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port) #endif FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix) -FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix) -FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix) -FN_GLOBAL_STRING(lp_ldap_idmap_suffix, &Globals.szLdapIdmapSuffix) -FN_GLOBAL_STRING(lp_ldap_group_suffix, &Globals.szLdapGroupSuffix) FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter) FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn) FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl) @@ -2998,56 +2991,56 @@ static BOOL handle_debug_list( const char *pszParmValueIn, char **ptr ) } /*************************************************************************** - Handle setting ldap suffix and determines whether ldap machine suffix needs - to be set as well. - - Set all of the sub suffix strings to be the 'ldap suffix' by default + Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined. ***************************************************************************/ -static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr ) +static char* append_ldap_suffix( const char *str ) { - pstring suffix; - - pstrcpy(suffix, pszParmValue); + char *suffix_string; - /* set defaults for the the sub-suffixes */ - - if (! *Globals.szLdapMachineSuffix ) - string_set(&Globals.szLdapMachineSuffix, suffix); - if (! *Globals.szLdapUserSuffix ) - string_set(&Globals.szLdapUserSuffix, suffix); - if (! *Globals.szLdapGroupSuffix ) - string_set(&Globals.szLdapGroupSuffix, suffix); - if (! *Globals.szLdapIdmapSuffix ) - string_set(&Globals.szLdapIdmapSuffix, suffix); - - string_set(ptr, suffix); - return True; + + if (!lp_talloc) + lp_talloc = talloc_init("lp_talloc"); + + suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix ); + if ( !suffix_string ) { + DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n")); + return NULL; + } + + return suffix_string; } -/*************************************************************************** - Handle the ldap sub suffix option. - Always append the 'ldap suffix' if it is set -***************************************************************************/ +char *lp_ldap_machine_suffix() +{ + if (Globals.szLdapMachineSuffix[0]) + return append_ldap_suffix(Globals.szLdapMachineSuffix); + + return lp_string(Globals.szLdapSuffix); +} -static BOOL handle_ldap_sub_suffix( const char *pszParmValue, char **ptr) +char *lp_ldap_user_suffix() { - pstring suffix; - - pstrcpy(suffix, pszParmValue); + if (Globals.szLdapUserSuffix[0]) + return append_ldap_suffix(Globals.szLdapUserSuffix); - if (! *Globals.szLdapSuffix ) { - string_set( ptr, suffix ); - return True; - } - else { - if ( *pszParmValue ) - pstrcat(suffix, ","); - pstrcat(suffix, Globals.szLdapSuffix); - } - - string_set( ptr, suffix ); - return True; + return lp_string(Globals.szLdapSuffix); +} + +char *lp_ldap_group_suffix() +{ + if (Globals.szLdapGroupSuffix[0]) + return append_ldap_suffix(Globals.szLdapGroupSuffix); + + return lp_string(Globals.szLdapSuffix); +} + +char *lp_ldap_idmap_suffix() +{ + if (Globals.szLdapIdmapSuffix[0]) + return append_ldap_suffix(Globals.szLdapIdmapSuffix); + + return lp_string(Globals.szLdapSuffix); } /*************************************************************************** -- cgit From bf0c18d4180a1c1ce5dd6eb8b14117d4ec1afa2d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Nov 2003 19:20:51 +0000 Subject: Fix Jerry's no-proto bug :-). Jeremy. (This used to be commit 2b39e3f12a12f0863bf76d996c0d0db422d593bc) --- source3/param/loadparm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 6f2b798720..8e6064ab59 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -3011,7 +3011,7 @@ static char* append_ldap_suffix( const char *str ) return suffix_string; } -char *lp_ldap_machine_suffix() +char *lp_ldap_machine_suffix(void) { if (Globals.szLdapMachineSuffix[0]) return append_ldap_suffix(Globals.szLdapMachineSuffix); @@ -3019,7 +3019,7 @@ char *lp_ldap_machine_suffix() return lp_string(Globals.szLdapSuffix); } -char *lp_ldap_user_suffix() +char *lp_ldap_user_suffix(void) { if (Globals.szLdapUserSuffix[0]) return append_ldap_suffix(Globals.szLdapUserSuffix); @@ -3027,7 +3027,7 @@ char *lp_ldap_user_suffix() return lp_string(Globals.szLdapSuffix); } -char *lp_ldap_group_suffix() +char *lp_ldap_group_suffix(void) { if (Globals.szLdapGroupSuffix[0]) return append_ldap_suffix(Globals.szLdapGroupSuffix); @@ -3035,7 +3035,7 @@ char *lp_ldap_group_suffix() return lp_string(Globals.szLdapSuffix); } -char *lp_ldap_idmap_suffix() +char *lp_ldap_idmap_suffix(void) { if (Globals.szLdapIdmapSuffix[0]) return append_ldap_suffix(Globals.szLdapIdmapSuffix); -- cgit From 1a125f5e402ad433a7192d9c5f5cfbb9593710b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Nov 2003 23:01:34 +0000 Subject: Fix for rename across filesystems. Noticed by Rainer Link . Jeremy. (This used to be commit f68c2ff0f3307612ddbe62b8cc2ea12251d54ec6) --- source3/smbd/vfs-wrap.c | 100 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c index a76a7a6abd..378a0a1e53 100644 --- a/source3/smbd/vfs-wrap.c +++ b/source3/smbd/vfs-wrap.c @@ -237,14 +237,104 @@ ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, return result; } +/********************************************************* + For rename across filesystems Patch from Warren Birnbaum + +**********************************************************/ + +static int copy_reg(const char *source, const char *dest) +{ + SMB_STRUCT_STAT source_stats; + int saved_errno; + int ifd = -1; + int ofd = -1; + + if (sys_lstat (source, &source_stats) == -1) + return -1; + + if (!S_ISREG (source_stats.st_mode)) + return -1; + + if((ifd = sys_open (source, O_RDONLY, 0)) < 0) + return -1; + + if (unlink (dest) && errno != ENOENT) + return -1; + +#ifdef O_NOFOLLOW + if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 ) +#else + if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 ) +#endif + goto err; + + if (transfer_file(ifd, ofd, (size_t)-1) == -1) + goto err; + + /* + * Try to preserve ownership. For non-root it might fail, but that's ok. + * But root probably wants to know, e.g. if NFS disallows it. + */ + + if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) + goto err; + + /* + * fchown turns off set[ug]id bits for non-root, + * so do the chmod last. + */ + +#if defined(HAVE_FCHMOD) + if (fchmod (ofd, source_stats.st_mode & 07777)) +#else + if (chmod (dest, source_stats.st_mode & 07777)) +#endif + goto err; + + if (close (ifd) == -1) + goto err; + + if (close (ofd) == -1) + return -1; + + /* Try to copy the old file's modtime and access time. */ + { + struct utimbuf tv; + + tv.actime = source_stats.st_atime; + tv.modtime = source_stats.st_mtime; + utime(dest, &tv); + } + + if (unlink (source) == -1) + return -1; + + return 0; + + err: + + saved_errno = errno; + if (ifd != -1) + close(ifd); + if (ofd != -1) + close(ofd); + errno = saved_errno; + return -1; +} + int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) { - int result; + int result; - START_PROFILE(syscall_rename); - result = rename(old, new); - END_PROFILE(syscall_rename); - return result; + START_PROFILE(syscall_rename); + result = rename(old, new); + if (errno == EXDEV) { + /* Rename across filesystems needed. */ + result = copy_reg(old, new); + } + + END_PROFILE(syscall_rename); + return result; } int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd) -- cgit From 3c101594ddb9b8be9378ddd00c175a1fcf04a577 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 22 Nov 2003 04:35:36 +0000 Subject: Ensure that items in a list of strings containing whitespace are written out surrounded by single quotes. This means that both double and single quotes are now used to surround strings in smb.conf. This is a slight change from the previous behavior but needed or else things like printer admin = +ntadmin, 'VALE\Domain, Admin' get written to smb.conf by SWAT. (This used to be commit 59e9d6e301c752e99fb6a50204d7941f7f84566a) --- source3/lib/util_str.c | 2 +- source3/param/loadparm.c | 10 +++++++--- source3/web/swat.c | 12 ++++++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index aa50b07f61..1aa33a1a4b 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -62,7 +62,7 @@ BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize) /* copy over the token */ pbuf = buff; for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) { - if (*s == '\"') { + if (*s == '\"' || *s == '\'') { quoted = !quoted; } else { len++; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 8e6064ab59..b124c6fd3b 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -3310,9 +3310,13 @@ static void print_parameter(struct parm_struct *p, void *ptr, FILE * f) if ((char ***)ptr && *(char ***)ptr) { char **list = *(char ***)ptr; - for (; *list; list++) - fprintf(f, "%s%s", *list, - ((*(list+1))?", ":"")); + for (; *list; list++) { + /* surround strings with whitespace in single quotes */ + if ( strchr_m( *list, ' ' ) ) + fprintf(f, "\'%s\'%s", *list, ((*(list+1))?", ":"")); + else + fprintf(f, "%s%s", *list, ((*(list+1))?", ":"")); + } } break; diff --git a/source3/web/swat.c b/source3/web/swat.c index f4046b46a2..1faef46e25 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -212,7 +212,11 @@ static void show_parameter(int snum, struct parm_struct *parm) if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) { char **list = *(char ***)ptr; for (;*list;list++) { - d_printf("%s%s", *list, ((*(list+1))?" ":"")); + /* enclose in quotes if the string contains a space */ + if ( strchr_m(*list, ' ') ) + d_printf("\'%s\'%s", *list, ((*(list+1))?", ":"")); + else + d_printf("%s%s", *list, ((*(list+1))?", ":"")); } } d_printf("\">"); @@ -221,7 +225,11 @@ static void show_parameter(int snum, struct parm_struct *parm) if (parm->def.lvalue) { char **list = (char **)(parm->def.lvalue); for (; *list; list++) { - d_printf("%s%s", *list, ((*(list+1))?" ":"")); + /* enclose in quotes if the string contains a space */ + if ( strchr_m(*list, ' ') ) + d_printf("\'%s\'%s", *list, ((*(list+1))?", ":"")); + else + d_printf("%s%s", *list, ((*(list+1))?", ":"")); } } d_printf("\'\">"); -- cgit From 177ff4d64c9a8891e827e927bd2354e28d4cc9d6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 22 Nov 2003 04:49:32 +0000 Subject: fix winbind ping call so that SWAT correctly determines if winbindd is running; bug 398 (This used to be commit cb12d519cc40b964d022886538044e8613931199) --- source3/web/diagnose.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/source3/web/diagnose.c b/source3/web/diagnose.c index efd6d1d0a1..46432c41f8 100644 --- a/source3/web/diagnose.c +++ b/source3/web/diagnose.c @@ -31,11 +31,7 @@ NSS_STATUS winbindd_request(int req_type, BOOL winbindd_running(void) { - - if (winbindd_request(WINBINDD_PING, NULL, NULL)) - return False; - - return True; + return winbind_ping(); } #endif -- cgit From a2b82b408b528a99037a390aabad867c25604836 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 22 Nov 2003 06:17:46 +0000 Subject: debug and swat fixes from 3.0 (This used to be commit 52c1973f39f4c4161097843fcf395e0102531575) --- source3/libsmb/trusts_util.c | 1 + source3/web/cgi.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index c18641bc84..2c6eb1b55a 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -181,6 +181,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, done: /* cleanup */ if (cli) { + DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n")); cli_nt_session_close( cli ); cli_shutdown( cli ); } diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 49a8fa92de..07e3ee38fb 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -355,7 +355,8 @@ static BOOL cgi_handle_authorization(char *line) } err: - cgi_setup_error("401 Bad Authorization", "", + cgi_setup_error("401 Bad Authorization", + "WWW-Authenticate: Basic realm=\"SWAT\"\r\n", "username or password incorrect"); passwd_free(&pass); -- cgit From 354c0fbc91c49f71c4760f88c0fb9e7fba11413c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Nov 2003 13:29:02 +0000 Subject: (merge from 3.0) Changes all over the shop, but all towards: - NTLM2 support in the server - KEY_EXCH support in the server - variable length session keys. In detail: - NTLM2 is an extension of NTLMv1, that is compatible with existing domain controllers (unlike NTLMv2, which requires a DC upgrade). * This is known as 'NTLMv2 session security' * (This is not yet implemented on the RPC pipes however, so there may well still be issues for PDC setups, particuarly around password changes. We do not fully understand the sign/seal implications of NTLM2 on RPC pipes.) This requires modifications to our authentication subsystem, as we must handle the 'challege' input into the challenge-response algorithm being changed. This also needs to be turned off for 'security=server', which does not support this. - KEY_EXCH is another 'security' mechanism, whereby the session key actually used by the server is sent by the client, rather than being the shared-secret directly or indirectly. - As both these methods change the session key, the auth subsystem needed to be changed, to 'override' session keys provided by the backend. - There has also been a major overhaul of the NTLMSSP subsystem, to merge the 'client' and 'server' functions, so they both operate on a single structure. This should help the SPNEGO implementation. - The 'names blob' in NTLMSSP is always in unicode - never in ascii. Don't make an ascii version ever. - The other big change is to allow variable length session keys. We have always assumed that session keys are 16 bytes long - and padded to this length if shorter. However, Kerberos session keys are 8 bytes long, when the krb5 login uses DES. * This fix allows SMB signging on machines not yet running MIT KRB5 1.3.1. * - Add better DEBUG() messages to ntlm_auth, warning administrators of misconfigurations that prevent access to the privileged pipe. This should help reduce some of the 'it just doesn't work' issues. - Fix data_blob_talloc() to behave the same way data_blob() does when passed a NULL data pointer. (just allocate) REMEMBER to make clean after this commit - I have changed plenty of data structures... Andrew Bartlett (This used to be commit 57a895aaabacc0c9147344d097d333793b77c947) --- source3/auth/auth.c | 3 + source3/auth/auth_ntlmssp.c | 81 +++- source3/auth/auth_sam.c | 64 +++- source3/auth/auth_util.c | 24 +- source3/include/auth.h | 7 +- source3/include/client.h | 4 +- source3/include/includes.h | 2 +- source3/include/ntdomain.h | 2 +- source3/include/ntlmssp.h | 98 +++-- source3/include/smb.h | 2 +- source3/lib/data_blob.c | 14 +- source3/libads/kerberos_verify.c | 2 +- source3/libsmb/cliconnect.c | 99 +++-- source3/libsmb/clientgen.c | 5 +- source3/libsmb/clikrb5.c | 16 +- source3/libsmb/clispnego.c | 2 +- source3/libsmb/ntlmssp.c | 741 +++++++++++++++++++++++++------------ source3/libsmb/ntlmssp_parse.c | 33 +- source3/libsmb/ntlmssp_sign.c | 126 ++++--- source3/libsmb/smb_signing.c | 26 +- source3/libsmb/smbencrypt.c | 6 +- source3/nsswitch/winbindd_cm.c | 5 +- source3/nsswitch/winbindd_pam.c | 10 +- source3/rpc_client/cli_netlogon.c | 12 +- source3/rpc_client/cli_pipe.c | 31 +- source3/rpc_client/cli_samr.c | 14 +- source3/rpc_parse/parse_net.c | 11 +- source3/rpc_parse/parse_samr.c | 20 +- source3/rpc_server/srv_netlog_nt.c | 23 +- source3/rpc_server/srv_pipe.c | 12 +- source3/rpc_server/srv_pipe_hnd.c | 2 +- source3/rpc_server/srv_samr_nt.c | 18 +- source3/smbd/password.c | 23 +- source3/smbd/sesssetup.c | 32 +- source3/utils/ntlm_auth.c | 184 +++++---- 35 files changed, 1157 insertions(+), 597 deletions(-) diff --git a/source3/auth/auth.c b/source3/auth/auth.c index 553d9a686e..20dccc6592 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -88,6 +88,8 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context) return auth_context->challenge.data; } + auth_context->challenge_may_be_modified = False; + for (auth_method = auth_context->auth_method_list; auth_method; auth_method = auth_method->next) { if (auth_method->get_chal == NULL) { DEBUG(5, ("auth_get_challenge: module %s did not want to specify a challenge\n", auth_method->name)); @@ -127,6 +129,7 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context) chal, sizeof(chal)); challenge_set_by = "random"; + auth_context->challenge_may_be_modified = True; } DEBUG(5, ("auth_context challenge created by %s\n", challenge_set_by)); diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index 3af0cbaada..a5ce101e5e 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -23,13 +23,59 @@ #include "includes.h" -static const uint8 *auth_ntlmssp_get_challenge(struct ntlmssp_state *ntlmssp_state) +/** + * Return the challenge as determined by the authentication subsystem + * @return an 8 byte random challenge + */ + +static const uint8 *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state) { AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context; return auth_ntlmssp_state->auth_context->get_ntlm_challenge(auth_ntlmssp_state->auth_context); } -static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state) +/** + * Some authentication methods 'fix' the challenge, so we may not be able to set it + * + * @return If the effective challenge used by the auth subsystem may be modified + */ +static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state) +{ + AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context; + struct auth_context *auth_context = auth_ntlmssp_state->auth_context; + + return auth_context->challenge_may_be_modified; +} + +/** + * NTLM2 authentication modifies the effective challange, + * @param challenge The new challenge value + */ +static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) +{ + AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context; + struct auth_context *auth_context = auth_ntlmssp_state->auth_context; + + SMB_ASSERT(challenge->length == 8); + + auth_context->challenge = data_blob_talloc(auth_context->mem_ctx, + challenge->data, challenge->length); + + auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)"; + + DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by)); + DEBUG(5, ("challenge is: \n")); + dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length); + return NT_STATUS_OK; +} + +/** + * Check the password on an NTLMSSP login. + * + * Return the session keys used on the connection. + */ + +static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key) { AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context; uint32 auth_flags = AUTH_FLAG_NONE; @@ -45,7 +91,7 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state) auth_flags |= AUTH_FLAG_NTLM_RESP; } else if (auth_ntlmssp_state->ntlmssp_state->nt_resp.length > 24) { auth_flags |= AUTH_FLAG_NTLMv2_RESP; - }; + } /* the client has given us its machine name (which we otherwise would not get on port 445). we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ @@ -71,10 +117,26 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state) return nt_status; } - nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, user_info, &auth_ntlmssp_state->server_info); - + nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, + user_info, &auth_ntlmssp_state->server_info); + free_user_info(&user_info); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + if (auth_ntlmssp_state->server_info->nt_session_key.length) { + DEBUG(10, ("Got NT session key of length %u\n", auth_ntlmssp_state->server_info->nt_session_key.length)); + *nt_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, + auth_ntlmssp_state->server_info->nt_session_key.data, + auth_ntlmssp_state->server_info->nt_session_key.length); + } + if (auth_ntlmssp_state->server_info->lm_session_key.length) { + DEBUG(10, ("Got LM session key of length %u\n", auth_ntlmssp_state->server_info->lm_session_key.length)); + *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, + auth_ntlmssp_state->server_info->lm_session_key.data, + auth_ntlmssp_state->server_info->lm_session_key.length); + } return nt_status; } @@ -106,18 +168,20 @@ NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) (*auth_ntlmssp_state)->ntlmssp_state->auth_context = (*auth_ntlmssp_state); (*auth_ntlmssp_state)->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; + (*auth_ntlmssp_state)->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; + (*auth_ntlmssp_state)->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; (*auth_ntlmssp_state)->ntlmssp_state->check_password = auth_ntlmssp_check_password; (*auth_ntlmssp_state)->ntlmssp_state->server_role = lp_server_role(); return NT_STATUS_OK; } -NTSTATUS auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) +void auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) { TALLOC_CTX *mem_ctx = (*auth_ntlmssp_state)->mem_ctx; if ((*auth_ntlmssp_state)->ntlmssp_state) { - ntlmssp_server_end(&(*auth_ntlmssp_state)->ntlmssp_state); + ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state); } if ((*auth_ntlmssp_state)->auth_context) { ((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context); @@ -127,11 +191,10 @@ NTSTATUS auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) } talloc_destroy(mem_ctx); *auth_ntlmssp_state = NULL; - return NT_STATUS_OK; } NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state, const DATA_BLOB request, DATA_BLOB *reply) { - return ntlmssp_server_update(auth_ntlmssp_state->ntlmssp_state, request, reply); + return ntlmssp_update(auth_ntlmssp_state->ntlmssp_state, request, reply); } diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index 2a00b6fb80..7352a9685b 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -33,7 +33,7 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, const uchar *part_passwd, const DATA_BLOB *sec_blob, - uint8 user_sess_key[16]) + DATA_BLOB *user_sess_key) { /* Finish the encryption of part_passwd. */ uchar p24[24]; @@ -56,7 +56,8 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, SMBOWFencrypt(part_passwd, sec_blob->data, p24); if (user_sess_key != NULL) { - SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key); + *user_sess_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key->data); } @@ -83,7 +84,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, const uchar *part_passwd, const DATA_BLOB *sec_blob, const char *user, const char *domain, - uint8 user_sess_key[16]) + DATA_BLOB *user_sess_key) { /* Finish the encryption of part_passwd. */ uchar kr[16]; @@ -120,7 +121,8 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); if (user_sess_key != NULL) { - SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key); + *user_sess_key = data_blob(NULL, 16); + SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); } #if DEBUG_PASSWORD @@ -148,7 +150,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, TALLOC_CTX *mem_ctx, SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, - uint8 user_sess_key[16]) + DATA_BLOB *user_sess_key, + DATA_BLOB *lm_sess_key) { uint16 acct_ctrl; const uint8 *nt_pw, *lm_pw; @@ -225,6 +228,16 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, if (smb_pwd_check_ntlmv1(&user_info->nt_resp, nt_pw, &auth_context->challenge, user_sess_key)) { + /* The LM session key for this response is not very secure, + so use it only if we otherwise allow LM authentication */ + lm_pw = pdb_get_lanman_passwd(sampass); + + if (lp_lanman_auth() && lm_pw) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } return NT_STATUS_OK; } else { DEBUG(3,("sam_password_ok: NT MD4 password check failed for user %s\n",pdb_get_username(sampass))); @@ -252,7 +265,12 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, DEBUG(4,("sam_password_ok: Checking LM password\n")); if (smb_pwd_check_ntlmv1(&user_info->lm_resp, lm_pw, &auth_context->challenge, - user_sess_key)) { + NULL)) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *user_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(first_8_lm_hash, 16); return NT_STATUS_OK; } } @@ -272,7 +290,7 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, nt_pw, &auth_context->challenge, user_info->smb_name.str, user_info->client_domain.str, - user_sess_key)) { + NULL)) { return NT_STATUS_OK; } @@ -281,7 +299,7 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, nt_pw, &auth_context->challenge, user_info->smb_name.str, "", - user_sess_key)) { + NULL)) { return NT_STATUS_OK; } @@ -292,7 +310,19 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, if (lp_ntlm_auth()) { if (smb_pwd_check_ntlmv1(&user_info->lm_resp, nt_pw, &auth_context->challenge, - user_sess_key)) { + NULL)) { + /* The session key for this response is still very odd. + It not very secure, so use it only if we otherwise + allow LM authentication */ + lm_pw = pdb_get_lanman_passwd(sampass); + + if (lp_lanman_auth() && lm_pw) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *user_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } return NT_STATUS_OK; } DEBUG(3,("sam_password_ok: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",pdb_get_username(sampass))); @@ -301,7 +331,6 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, DEBUG(3,("sam_password_ok: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",pdb_get_username(sampass))); return NT_STATUS_WRONG_PASSWORD; } - } /* Should not be reached, but if they send nothing... */ @@ -421,8 +450,8 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, SAM_ACCOUNT *sampass=NULL; BOOL ret; NTSTATUS nt_status; - uint8 user_sess_key[16]; - const uint8* lm_hash; + DATA_BLOB user_sess_key = data_blob(NULL, 0); + DATA_BLOB lm_sess_key = data_blob(NULL, 0); if (!user_info || !auth_context) { return NT_STATUS_UNSUCCESSFUL; @@ -446,7 +475,8 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, return NT_STATUS_NO_SUCH_USER; } - nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key); + nt_status = sam_password_ok(auth_context, mem_ctx, sampass, + user_info, &user_sess_key, &lm_sess_key); if (!NT_STATUS_IS_OK(nt_status)) { pdb_free_sam(&sampass); @@ -465,12 +495,8 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, return nt_status; } - lm_hash = pdb_get_lanman_passwd((*server_info)->sam_account); - if (lm_hash) { - memcpy((*server_info)->first_8_lm_hash, lm_hash, 8); - } - - memcpy((*server_info)->session_key, user_sess_key, sizeof(user_sess_key)); + (*server_info)->nt_session_key = user_sess_key; + (*server_info)->lm_session_key = lm_sess_key; return nt_status; } diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index d7d7f53e2d..5d3f8f0277 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -900,7 +900,13 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info) nt_status = make_server_info_sam(server_info, sampass); if (NT_STATUS_IS_OK(nt_status)) { + static const char zeros[16]; (*server_info)->guest = True; + + /* annoying, but the Guest really does have a session key, + and it is all zeros! */ + (*server_info)->nt_session_key = data_blob(zeros, sizeof(zeros)); + (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros)); } return nt_status; @@ -992,6 +998,8 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, auth_serversupplied_info **server_info, NET_USER_INFO_3 *info3) { + static const char zeros[16]; + NTSTATUS nt_status = NT_STATUS_OK; char *found_username; const char *nt_domain; @@ -1210,10 +1218,20 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, (*server_info)->ptok = token; SAFE_FREE(all_group_SIDs); + + /* ensure we are never given NULL session keys */ - memcpy((*server_info)->session_key, info3->user_sess_key, sizeof((*server_info)->session_key)/* 16 */); - memcpy((*server_info)->first_8_lm_hash, info3->padding, 8); + if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) { + (*server_info)->nt_session_key = data_blob(NULL, 0); + } else { + (*server_info)->nt_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key)); + } + if (memcmp(info3->padding, zeros, sizeof(zeros)) == 0) { + (*server_info)->lm_session_key = data_blob(NULL, 0); + } else { + (*server_info)->lm_session_key = data_blob(info3->padding, 16); + } return NT_STATUS_OK; } @@ -1256,6 +1274,8 @@ void free_server_info(auth_serversupplied_info **server_info) delete_nt_token( &(*server_info)->ptok ); SAFE_FREE((*server_info)->groups); SAFE_FREE((*server_info)->unix_name); + data_blob_free(&(*server_info)->lm_session_key); + data_blob_free(&(*server_info)->nt_session_key); ZERO_STRUCT(**server_info); } SAFE_FREE(*server_info); diff --git a/source3/include/auth.h b/source3/include/auth.h index 6b42418be8..ecf4d539d8 100644 --- a/source3/include/auth.h +++ b/source3/include/auth.h @@ -87,10 +87,9 @@ typedef struct auth_serversupplied_info NT_USER_TOKEN *ptok; - uint8 session_key[16]; + DATA_BLOB nt_session_key; + DATA_BLOB lm_session_key; - uint8 first_8_lm_hash[8]; - uint32 sam_fill_level; /* How far is this structure filled? */ SAM_ACCOUNT *sam_account; @@ -107,6 +106,8 @@ struct auth_context { /* Who set this up in the first place? */ const char *challenge_set_by; + BOOL challenge_may_be_modified; + struct auth_methods *challenge_set_method; /* What order are the various methods in? Try to stop it changing under us */ struct auth_methods *auth_method_list; diff --git a/source3/include/client.h b/source3/include/client.h index 598e6c0bda..968b73f0b4 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -113,7 +113,7 @@ struct cli_state { /* the session key for this CLI, outside any per-pipe authenticaion */ - unsigned char user_session_key[16]; + DATA_BLOB user_session_key; /* * Only used in NT domain calls. @@ -133,7 +133,7 @@ struct cli_state { schannel. */ struct netsec_auth_struct auth_info; - NTLMSSP_CLIENT_STATE *ntlmssp_pipe_state; + NTLMSSP_STATE *ntlmssp_pipe_state; unsigned char sess_key[16]; /* Current session key. */ DOM_CRED clnt_cred; /* Client credential. */ diff --git a/source3/include/includes.h b/source3/include/includes.h index 92c5f847dd..4e7913ea38 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -1303,7 +1303,7 @@ krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt); krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters); krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes); void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes); -BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote); +BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote); #endif /* HAVE_KRB5 */ /* TRUE and FALSE are part of the C99 standard and gcc, but diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index d9fff4d2a9..eaedc7ea9b 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -245,7 +245,7 @@ typedef struct pipes_struct fstring pipe_user_name; struct current_user pipe_user; - uint8 session_key[16]; + DATA_BLOB session_key; /* * Set to true when an RPC bind has been done on this pipe. diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h index f1b1bc25e4..681d4071db 100644 --- a/source3/include/ntlmssp.h +++ b/source3/include/ntlmssp.h @@ -30,6 +30,7 @@ enum NTLMSSP_ROLE /* NTLMSSP message types */ enum NTLM_MESSAGE_TYPE { + NTLMSSP_INITIAL = 0 /* samba internal state */, NTLMSSP_NEGOTIATE = 1, NTLMSSP_CHALLENGE = 2, NTLMSSP_AUTH = 3, @@ -70,29 +71,10 @@ enum NTLM_MESSAGE_TYPE typedef struct ntlmssp_state { TALLOC_CTX *mem_ctx; + unsigned int ref_count; enum NTLMSSP_ROLE role; - BOOL unicode; - char *user; - char *domain; - char *workstation; - DATA_BLOB lm_resp; - DATA_BLOB nt_resp; - DATA_BLOB chal; - void *auth_context; - const uint8 *(*get_challenge)(struct ntlmssp_state *ntlmssp_state); - NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state); - - const char *(*get_global_myname)(void); - const char *(*get_domain)(void); - - int server_role; + enum server_types server_role; uint32 expected_state; -} NTLMSSP_STATE; - -typedef struct ntlmssp_client_state -{ - TALLOC_CTX *mem_ctx; - unsigned int ref_count; BOOL unicode; BOOL use_ntlmv2; @@ -102,30 +84,78 @@ typedef struct ntlmssp_client_state char *password; char *server_domain; - const char *(*get_global_myname)(void); - const char *(*get_domain)(void); + DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */ - DATA_BLOB chal; + DATA_BLOB chal; /* Random challenge as input into the actual NTLM (or NTLM2) authentication */ DATA_BLOB lm_resp; DATA_BLOB nt_resp; DATA_BLOB session_key; - uint32 neg_flags; + uint32 neg_flags; /* the current state of negotiation with the NTLMSSP partner */ + void *auth_context; + + /** + * Callback to get the 'challenge' used for NTLM authentication. + * + * @param ntlmssp_state This structure + * @return 8 bytes of challnege data, determined by the server to be the challenge for NTLM authentication + * + */ + const uint8 *(*get_challenge)(const struct ntlmssp_state *ntlmssp_state); + + /** + * Callback to find if the challenge used by NTLM authentication may be modified + * + * The NTLM2 authentication scheme modifies the effective challenge, but this is not compatiable with the + * current 'security=server' implementation.. + * + * @param ntlmssp_state This structure + * @return Can the challenge be set to arbitary values? + * + */ + BOOL (*may_set_challenge)(const struct ntlmssp_state *ntlmssp_state); + + /** + * Callback to set the 'challenge' used for NTLM authentication. + * + * The callback may use the void *auth_context to store state information, but the same value is always available + * from the DATA_BLOB chal on this structure. + * + * @param ntlmssp_state This structure + * @param challange 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication + * + */ + NTSTATUS (*set_challenge)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge); + + /** + * Callback to check the user's password. + * + * The callback must reads the feilds of this structure for the information it needs on the user + * @param ntlmssp_state This structure + * @param nt_session_key If an NT session key is returned by the authentication process, return it here + * @param lm_session_key If an LM session key is returned by the authentication process, return it here + * + */ + NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key); + + const char *(*get_global_myname)(void); + const char *(*get_domain)(void); + /* SMB Signing */ uint32 ntlmssp_seq_num; /* ntlmv2 */ - char cli_sign_const[16]; - char cli_seal_const[16]; - char srv_sign_const[16]; - char srv_seal_const[16]; + char send_sign_const[16]; + char send_seal_const[16]; + char recv_sign_const[16]; + char recv_seal_const[16]; - unsigned char cli_sign_hash[258]; - unsigned char cli_seal_hash[258]; - unsigned char srv_sign_hash[258]; - unsigned char srv_seal_hash[258]; + unsigned char send_sign_hash[258]; + unsigned char send_seal_hash[258]; + unsigned char recv_sign_hash[258]; + unsigned char recv_seal_hash[258]; /* ntlmv1 */ unsigned char ntlmssp_hash[258]; @@ -135,5 +165,5 @@ typedef struct ntlmssp_client_state Store it here, until we need it */ DATA_BLOB stored_response; -} NTLMSSP_CLIENT_STATE; +} NTLMSSP_STATE; diff --git a/source3/include/smb.h b/source3/include/smb.h index 689e6ebe1d..bef6bef691 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1548,7 +1548,7 @@ typedef struct user_struct NT_USER_TOKEN *nt_user_token; - uint8 session_key[16]; + DATA_BLOB session_key; char *session_keystr; /* used by utmp and pam session code. TDB key string */ diff --git a/source3/lib/data_blob.c b/source3/lib/data_blob.c index 4056212fc5..83afc591a1 100644 --- a/source3/lib/data_blob.c +++ b/source3/lib/data_blob.c @@ -61,14 +61,20 @@ DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length) { DATA_BLOB ret; - if (!p || !length) { + if (!length) { ZERO_STRUCT(ret); return ret; } - ret.data = talloc_memdup(mem_ctx, p, length); - if (ret.data == NULL) - smb_panic("data_blob_talloc: talloc_memdup failed.\n"); + if (p) { + ret.data = talloc_memdup(mem_ctx, p, length); + if (ret.data == NULL) + smb_panic("data_blob_talloc: talloc_memdup failed.\n"); + } else { + ret.data = talloc(mem_ctx, length); + if (ret.data == NULL) + smb_panic("data_blob_talloc: talloc failed.\n"); + } ret.length = length; ret.free = NULL; diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index cdea5a2fe4..b0efb8f598 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -162,7 +162,7 @@ static BOOL setup_keytab(krb5_context context, NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, DATA_BLOB *ap_rep, - uint8 session_key[16]) + DATA_BLOB *session_key) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; krb5_context context = NULL; diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b5f7b97ae8..a920a1b7ff 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -241,9 +241,16 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, return True; } -static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) +/** + * Set the user session key for a connection + * @param cli The cli structure to add it too + * @param session_key The session key used. (A copy of this is taken for the cli struct) + * + */ + +static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) { - memcpy(cli->user_session_key, session_key.data, MIN(session_key.length, sizeof(cli->user_session_key))); + cli->user_session_key = data_blob(session_key.data, session_key.length); } /**************************************************************************** @@ -311,7 +318,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - cli_simple_set_signing(cli, session_key.data, nt_response); + cli_simple_set_signing(cli, session_key, nt_response); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -373,14 +380,16 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (session_key.data) { /* Have plaintext orginal */ - set_cli_session_key(cli, session_key); + cli_set_session_key(cli, session_key); } ret = True; end: data_blob_free(&lm_response); data_blob_free(&nt_response); - data_blob_free(&session_key); + + if (!ret) + data_blob_free(&session_key); return ret; } @@ -484,19 +493,19 @@ static void use_in_memory_ccache(void) { Do a spnego/kerberos encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) +static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) { DATA_BLOB blob2, negTokenTarg; - unsigned char session_key_krb5[16]; + DATA_BLOB session_key_krb5; DATA_BLOB null_blob = data_blob(NULL, 0); DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(principal, 0, session_key_krb5); + negTokenTarg = spnego_gen_negTokenTarg(principal, 0, &session_key_krb5); if (!negTokenTarg.data) - return False; + return NT_STATUS_UNSUCCESSFUL; #if 0 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); @@ -509,9 +518,16 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *princi /* we don't need this blob for kerberos */ data_blob_free(&blob2); + cli_set_session_key(cli, session_key_krb5); + data_blob_free(&negTokenTarg); - return !cli_is_error(cli); + if (cli_is_error(cli)) { + if (NT_STATUS_IS_OK(cli_nt_error(cli))) { + return NT_STATUS_UNSUCCESSFUL; + } + } + return NT_STATUS_OK; } #endif /* HAVE_KRB5 */ @@ -520,10 +536,10 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *princi Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, +static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, const char *pass, const char *workgroup) { - struct ntlmssp_client_state *ntlmssp_state; + struct ntlmssp_state *ntlmssp_state; NTSTATUS nt_status; int turn = 1; DATA_BLOB msg1; @@ -534,21 +550,21 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, cli_temp_set_signing(cli); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { - return False; + return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { - return False; + return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, workgroup))) { - return False; + return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) { - return False; + return nt_status; } do { - nt_status = ntlmssp_client_update(ntlmssp_state, + nt_status = ntlmssp_update(ntlmssp_state, blob_in, &blob_out); data_blob_free(&blob_in); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { @@ -562,18 +578,27 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, } cli_simple_set_signing(cli, - ntlmssp_state->session_key.data, + data_blob(ntlmssp_state->session_key.data, ntlmssp_state->session_key.length), null_blob); /* now send that blob on its way */ if (!cli_session_setup_blob_send(cli, msg1)) { - return False; + DEBUG(3, ("Failed to send NTLMSSP/SPENGO blob to server!\n")); + nt_status = NT_STATUS_UNSUCCESSFUL; + } else { + data_blob_free(&msg1); + + blob = cli_session_setup_blob_receive(cli); + + nt_status = cli_nt_error(cli); + if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) { + if (cli->smb_rw_error == READ_BAD_SIG) { + nt_status = NT_STATUS_ACCESS_DENIED; + } else { + nt_status = NT_STATUS_UNSUCCESSFUL; + } + } } - data_blob_free(&msg1); - - blob = cli_session_setup_blob_receive(cli); - - nt_status = cli_nt_error(cli); } if (!blob.length) { @@ -606,24 +631,22 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, if (NT_STATUS_IS_OK(nt_status)) { fstrcpy(cli->server_domain, ntlmssp_state->server_domain); - set_cli_session_key(cli, ntlmssp_state->session_key); + cli_set_session_key(cli, ntlmssp_state->session_key); } /* we have a reference conter on ntlmssp_state, if we are signing then the state will be kept by the signing engine */ - if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { - return False; - } - - return (NT_STATUS_IS_OK(nt_status)); + ntlmssp_end(&ntlmssp_state); + + return nt_status; } /**************************************************************************** Do a spnego encrypted session setup. ****************************************************************************/ -BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, +NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, const char *pass, const char *workgroup) { char *principal; @@ -651,7 +674,7 @@ BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, reply */ if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { data_blob_free(&blob); - return False; + return NT_STATUS_INVALID_PARAMETER; } data_blob_free(&blob); @@ -681,7 +704,7 @@ BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, if (ret){ DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); - return False; + return NT_STATUS_LOGON_FAILURE; } } @@ -773,8 +796,14 @@ BOOL cli_session_setup(struct cli_state *cli, /* if the server supports extended security then use SPNEGO */ - if (cli->capabilities & CAP_EXTENDED_SECURITY) - return cli_session_setup_spnego(cli, user, pass, workgroup); + if (cli->capabilities & CAP_EXTENDED_SECURITY) { + NTSTATUS nt_status; + if (!NT_STATUS_IS_OK(nt_status = cli_session_setup_spnego(cli, user, pass, workgroup))) { + DEBUG(3, ("SPENGO login failed: %s\n", get_friendly_nt_error_msg(nt_status))); + return False; + } + return True; + } /* otherwise do a NT1 style session setup */ diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9b54acf775..0873700fc0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -339,7 +339,7 @@ close the session void cli_nt_session_close(struct cli_state *cli) { if (cli->ntlmssp_pipe_state) { - ntlmssp_client_end(&cli->ntlmssp_pipe_state); + ntlmssp_end(&cli->ntlmssp_pipe_state); } if (cli->nt_pipe_fnum != 0) @@ -375,9 +375,10 @@ void cli_close_connection(struct cli_state *cli) cli_free_signing_context(cli); data_blob_free(&cli->secblob); + data_blob_free(&cli->user_session_key); if (cli->ntlmssp_pipe_state) - ntlmssp_client_end(&cli->ntlmssp_pipe_state); + ntlmssp_end(&cli->ntlmssp_pipe_state); if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 1fccc04a01..5568b5e033 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -307,7 +307,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16]) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *session_key_krb5) { krb5_error_code retval; krb5_data packet; @@ -369,7 +369,7 @@ failed: return data_blob(NULL, 0); } - BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote) + BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote) { krb5_keyblock *skey; krb5_error_code err; @@ -383,11 +383,11 @@ failed: err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); if (err == 0 && skey != NULL) { DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); - if (KRB5_KEY_LENGTH(skey) == 16) { - memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); - dump_data_pw("KRB5 Session Key:\n", session_key, 16); - ret = True; - } + *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + + ret = True; + krb5_free_keyblock(context, skey); } else { DEBUG(10, ("KRB5 error getting session key %d\n", err)); @@ -410,7 +410,7 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16]) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *session_key_krb5) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 63076a1a1c..92543736ff 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -323,7 +323,7 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsigned char session_key_krb5[16]) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *session_key_krb5) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index c51b599b04..a0da1efcc1 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -23,6 +23,35 @@ #include "includes.h" +static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB reply, DATA_BLOB *next_request); +static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB in, DATA_BLOB *out); +static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB reply, DATA_BLOB *next_request); +static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply); + +/** + * Callbacks for NTLMSSP - for both client and server operating modes + * + */ + +static const struct ntlmssp_callbacks { + enum NTLMSSP_ROLE role; + enum NTLM_MESSAGE_TYPE ntlmssp_command; + NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB in, DATA_BLOB *out); +} ntlmssp_callbacks[] = { + {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial}, + {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate}, + {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge}, + {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth}, + {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL}, + {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL} +}; + + /** * Print out the NTLMSSP flags for debugging * @param neg_flags The flags from the packet @@ -71,7 +100,7 @@ void debug_ntlmssp_flags(uint32 neg_flags) * */ -static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) +static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state) { static uchar chal[8]; generate_random_buffer(chal, sizeof(chal), False); @@ -79,6 +108,188 @@ static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) return chal; } +/** + * Default 'we can set the challenge to anything we like' implementation + * + */ + +static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state) +{ + return True; +} + +/** + * Default 'we can set the challenge to anything we like' implementation + * + * Does not actually do anything, as the value is always in the structure anyway. + * + */ + +static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) +{ + SMB_ASSERT(challenge->length == 8); + return NT_STATUS_OK; +} + +/** + * Set a username on an NTLMSSP context - ensures it is talloc()ed + * + */ + +NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) +{ + ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); + if (!ntlmssp_state->user) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a password on an NTLMSSP context - ensures it is talloc()ed + * + */ +NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) +{ + if (!password) { + ntlmssp_state->password = NULL; + } else { + ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); + if (!ntlmssp_state->password) { + return NT_STATUS_NO_MEMORY; + } + } + return NT_STATUS_OK; +} + +/** + * Set a domain on an NTLMSSP context - ensures it is talloc()ed + * + */ +NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) +{ + ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); + if (!ntlmssp_state->domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a workstation on an NTLMSSP context - ensures it is talloc()ed + * + */ +NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) +{ + ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation); + if (!ntlmssp_state->domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Store a DATA_BLOB containing an NTLMSSP response, for use later. + * This copies the data blob + */ + +NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state, + DATA_BLOB response) +{ + ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx, + response.data, response.length); + return NT_STATUS_OK; +} + +/** + * Next state function for the NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State + * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB + * @param out The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. + */ + +NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, + const DATA_BLOB in, DATA_BLOB *out) +{ + DATA_BLOB input; + uint32 ntlmssp_command; + int i; + + *out = data_blob(NULL, 0); + + if (!in.length && ntlmssp_state->stored_response.length) { + input = ntlmssp_state->stored_response; + + /* we only want to read the stored response once - overwrite it */ + ntlmssp_state->stored_response = data_blob(NULL, 0); + } else { + input = in; + } + + if (!input.length) { + switch (ntlmssp_state->role) { + case NTLMSSP_CLIENT: + ntlmssp_command = NTLMSSP_INITIAL; + break; + case NTLMSSP_SERVER: + /* 'datagram' mode - no neg packet */ + ntlmssp_command = NTLMSSP_NEGOTIATE; + break; + } + } else { + if (!msrpc_parse(&input, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); + dump_data(2, (const char *)input.data, input.length); + return NT_STATUS_INVALID_PARAMETER; + } + } + + if (ntlmssp_command != ntlmssp_state->expected_state) { + DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); + return NT_STATUS_INVALID_PARAMETER; + } + + for (i=0; ntlmssp_callbacks[i].fn; i++) { + if (ntlmssp_callbacks[i].role == ntlmssp_state->role + && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) { + return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out); + } + } + + DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", + ntlmssp_state->role, ntlmssp_command)); + + return NT_STATUS_INVALID_PARAMETER; +} + +/** + * End an NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State, free()ed by this function + */ + +void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + + (*ntlmssp_state)->ref_count--; + + if ((*ntlmssp_state)->ref_count == 0) { + data_blob_free(&(*ntlmssp_state)->chal); + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + + talloc_destroy(mem_ctx); + } + + *ntlmssp_state = NULL; + return; +} + /** * Determine correct target name flags for reply, given server role * and negotiated flags @@ -107,6 +318,46 @@ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, } } +static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, + uint32 neg_flags, BOOL allow_lm) { + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; + ntlmssp_state->unicode = True; + } else { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; + ntlmssp_state->unicode = False; + } + + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY && allow_lm) { + /* other end forcing us to use LM */ + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; + ntlmssp_state->use_ntlmv2 = False; + } else { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; + } + + if ((neg_flags & NTLMSSP_REQUEST_TARGET)) { + ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; + } + +} + + /** * Next state function for the Negotiate packet * @@ -150,31 +401,27 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, debug_ntlmssp_flags(neg_flags); } - cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); + ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); - data_blob_free(&ntlmssp_state->chal); - ntlmssp_state->chal = data_blob(cryptkey, 8); - - /* Give them the challenge. For now, ignore neg_flags and just - return the flags we want. Obviously this is not correct */ - - chal_flags = - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM; - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { - chal_flags |= NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->unicode = True; - } else { - chal_flags |= NTLMSSP_NEGOTIATE_OEM; - } + chal_flags = ntlmssp_state->neg_flags; target_name = ntlmssp_target_name(ntlmssp_state, neg_flags, &chal_flags); - - if (target_name == NULL) + if (target_name == NULL) return NT_STATUS_INVALID_PARAMETER; + /* Ask our caller what challenge they would like in the packet */ + cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); + + /* Check if we may set the challenge */ + if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + } + + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); + ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); + + /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; get_mydomname(dnsdomname); @@ -184,6 +431,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, get_myfullname(dnsname); strlower_m(dnsname); + /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { const char *target_name_dns = ""; @@ -194,16 +442,17 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, } msrpc_gen(&struct_blob, "aaaaa", - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN, target_name, - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN_DNS, target_name_dns, - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsdomname, - ntlmssp_state->unicode, 0, ""); + NTLMSSP_NAME_TYPE_DOMAIN, target_name, + NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), + NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, + NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, + 0, ""); } else { struct_blob = data_blob(NULL, 0); } { + /* Marshel the packet in the right format, be it unicode or ASCII */ const char *gen_string; if (ntlmssp_state->unicode) { gen_string = "CdUdbddB"; @@ -240,13 +489,27 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB request, DATA_BLOB *reply) { - DATA_BLOB sess_key; - uint32 ntlmssp_command, neg_flags; + DATA_BLOB encrypted_session_key = data_blob(NULL, 0); + DATA_BLOB nt_session_key = data_blob(NULL, 0); + DATA_BLOB lm_session_key = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob(NULL, 0); + uint32 ntlmssp_command, auth_flags; NTSTATUS nt_status; + /* used by NTLM2 */ + BOOL doing_ntlm2 = False; + + uchar session_nonce[16]; + uchar session_nonce_hash[16]; + const char *parse_string; + char *domain = NULL; + char *user = NULL; + char *workstation = NULL; /* parse the NTLMSSP packet */ + *reply = data_blob(NULL, 0); + #if 0 file_save("ntlmssp_auth.dat", request.data, request.length); #endif @@ -260,9 +523,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, data_blob_free(&ntlmssp_state->lm_resp); data_blob_free(&ntlmssp_state->nt_resp); - SAFE_FREE(ntlmssp_state->user); - SAFE_FREE(ntlmssp_state->domain); - SAFE_FREE(ntlmssp_state->workstation); + ntlmssp_state->user = NULL; + ntlmssp_state->domain = NULL; + ntlmssp_state->workstation = NULL; /* now the NTLMSSP encoded auth hashes */ if (!msrpc_parse(&request, parse_string, @@ -270,18 +533,73 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, &ntlmssp_command, &ntlmssp_state->lm_resp, &ntlmssp_state->nt_resp, - &ntlmssp_state->domain, - &ntlmssp_state->user, - &ntlmssp_state->workstation, - &sess_key, - &neg_flags)) { + &domain, + &user, + &workstation, + &encrypted_session_key, + &auth_flags)) { DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); dump_data(2, (const char *)request.data, request.length); - return NT_STATUS_INVALID_PARAMETER; + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + auth_flags = 0; + + /* Try again with a shorter string (Win9X truncates this packet) */ + if (ntlmssp_state->unicode) { + parse_string = "CdBBUUU"; + } else { + parse_string = "CdBBAAA"; + } + + /* now the NTLMSSP encoded auth hashes */ + if (!msrpc_parse(&request, parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &domain, + &user, + &workstation)) { + DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); + dump_data(2, (const char *)request.data, request.length); + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + + return NT_STATUS_INVALID_PARAMETER; + } } - data_blob_free(&sess_key); - + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + return nt_status; + } + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + return nt_status; + } + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) { + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + return nt_status; + } + + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n", ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length)); @@ -290,9 +608,98 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); #endif - nt_status = ntlmssp_state->check_password(ntlmssp_state); + /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a + client challenge - *reply = data_blob(NULL, 0); + However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful. + */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) { + struct MD5Context md5_session_nonce_ctx; + SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8); + + doing_ntlm2 = True; + + memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8); + memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8); + + MD5Init(&md5_session_nonce_ctx); + MD5Update(&md5_session_nonce_ctx, session_nonce, 16); + MD5Final(session_nonce_hash, &md5_session_nonce_ctx); + + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8); + + /* LM response is no longer useful */ + data_blob_free(&ntlmssp_state->lm_resp); + + /* We changed the effective challenge - set it */ + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) { + data_blob_free(&encrypted_session_key); + return nt_status; + } + } + } + + /* Finally, actually ask if the password is OK */ + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) { + data_blob_free(&encrypted_session_key); + return nt_status; + } + + dump_data_pw("NT session key:\n", nt_session_key.data, nt_session_key.length); + dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length); + + /* Handle the different session key derivation for NTLM2 */ + if (doing_ntlm2) { + if (nt_session_key.data && nt_session_key.length == 16) { + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + hmac_md5(nt_session_key.data, session_nonce, + sizeof(session_nonce), session_key.data); + dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); + + } + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { + if (lm_session_key.data && lm_session_key.length >= 8 && + ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + SMBsesskeygen_lmv1(lm_session_key.data, ntlmssp_state->lm_resp.data, + session_key.data); + dump_data_pw("LM session key:\n", session_key.data, session_key.length); + } + } else if (nt_session_key.data) { + session_key = nt_session_key; + dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + } + + /* With KEY_EXCH, the client supplies the proposed session key, + but encrypts it with the long-term key */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + if (!encrypted_session_key.data || encrypted_session_key.length != 16) { + data_blob_free(&encrypted_session_key); + DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", + encrypted_session_key.length)); + return NT_STATUS_INVALID_PARAMETER; + } else if (!session_key.data || session_key.length != 16) { + DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", + session_key.length)); + } else { + dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); + SamOEMhash(encrypted_session_key.data, + session_key.data, + encrypted_session_key.length); + ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + encrypted_session_key.data, + encrypted_session_key.length); + dump_data_pw("KEY_EXCH session key:\n", session_key.data, session_key.length); + } + } else { + ntlmssp_state->session_key = session_key; + } + + data_blob_free(&encrypted_session_key); + + /* allow arbitarily many authentications */ + ntlmssp_state->expected_state = NTLMSSP_AUTH; return nt_status; } @@ -316,8 +723,12 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) return NT_STATUS_NO_MEMORY; } + (*ntlmssp_state)->role = NTLMSSP_SERVER; + (*ntlmssp_state)->mem_ctx = mem_ctx; (*ntlmssp_state)->get_challenge = get_challenge; + (*ntlmssp_state)->set_challenge = set_challenge; + (*ntlmssp_state)->may_set_challenge = may_set_challenge; (*ntlmssp_state)->get_global_myname = global_myname; (*ntlmssp_state)->get_domain = lp_workgroup; @@ -325,73 +736,18 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; - return NT_STATUS_OK; -} - -/** - * End an NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State, free()ed by this function - */ - -NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - - data_blob_free(&(*ntlmssp_state)->chal); - data_blob_free(&(*ntlmssp_state)->lm_resp); - data_blob_free(&(*ntlmssp_state)->nt_resp); + (*ntlmssp_state)->ref_count = 1; - SAFE_FREE((*ntlmssp_state)->user); - SAFE_FREE((*ntlmssp_state)->domain); - SAFE_FREE((*ntlmssp_state)->workstation); + (*ntlmssp_state)->neg_flags = + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_NTLM2 | + NTLMSSP_NEGOTIATE_KEY_EXCH | + NTLMSSP_NEGOTIATE_SIGN; - talloc_destroy(mem_ctx); - *ntlmssp_state = NULL; return NT_STATUS_OK; } -/** - * Next state function for the NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. - */ - -NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, - const DATA_BLOB request, DATA_BLOB *reply) -{ - uint32 ntlmssp_command; - *reply = data_blob(NULL, 0); - - if (request.length) { - if (!msrpc_parse(&request, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - return NT_STATUS_INVALID_PARAMETER; - } - } else { - /* 'datagram' mode - no neg packet */ - ntlmssp_command = NTLMSSP_NEGOTIATE; - } - - if (ntlmssp_command != ntlmssp_state->expected_state) { - DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); - return NT_STATUS_INVALID_PARAMETER; - } - - if (ntlmssp_command == NTLMSSP_NEGOTIATE) { - return ntlmssp_server_negotiate(ntlmssp_state, request, reply); - } else if (ntlmssp_command == NTLMSSP_AUTH) { - return ntlmssp_server_auth(ntlmssp_state, request, reply); - } else { - DEBUG(1, ("unknown NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); - return NT_STATUS_INVALID_PARAMETER; - } -} - /********************************************************************* Client side NTLMSSP *********************************************************************/ @@ -405,11 +761,13 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, * @return Errors or NT_STATUS_OK. */ -static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_state, +static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, DATA_BLOB reply, DATA_BLOB *next_request) { if (ntlmssp_state->unicode) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + } else { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; } if (ntlmssp_state->use_ntlmv2) { @@ -426,6 +784,8 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat ntlmssp_state->get_domain(), ntlmssp_state->get_global_myname()); + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; + return NT_STATUS_MORE_PROCESSING_REQUIRED; } @@ -438,7 +798,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat * @return Errors or NT_STATUS_OK. */ -static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_state, +static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB reply, DATA_BLOB *next_request) { uint32 chal_flags, ntlmssp_command, unkn1, unkn2; @@ -469,17 +829,16 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st DEBUG(3, ("Got challenge flags:\n")); debug_ntlmssp_flags(chal_flags); - if (chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { + ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth()); + + if (ntlmssp_state->unicode) { if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { chal_parse_string = "CdUdbddB"; } else { chal_parse_string = "CdUdbdd"; } auth_gen_string = "CdBBUUUBd"; - ntlmssp_state->unicode = True; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; - } else if (chal_flags & NTLMSSP_NEGOTIATE_OEM) { + } else { if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { chal_parse_string = "CdAdbddB"; } else { @@ -487,32 +846,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st } auth_gen_string = "CdBBAAABd"; - - ntlmssp_state->unicode = False; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; - } else { - return NT_STATUS_INVALID_PARAMETER; - } - - if (chal_flags & NTLMSSP_NEGOTIATE_LM_KEY && lp_client_lanman_auth()) { - /* server forcing us to use LM */ - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; - ntlmssp_state->use_ntlmv2 = False; - } else { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - } - - if (!(chal_flags & NTLMSSP_NEGOTIATE_NTLM2)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - } - - if (!(chal_flags & NTLMSSP_NEGOTIATE_128)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; - } - - if (!(chal_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; } DEBUG(3, ("NTLMSSP: Set final flags:\n")); @@ -546,6 +879,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st if (!struct_blob.length) { /* be lazy, match win2k - we can't do NTLMv2 without it */ + DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -569,7 +903,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st uchar nt_session_key[16]; E_md4hash(ntlmssp_state->password, nt_hash); - lm_response = data_blob(NULL, 24); + lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); generate_random_buffer(lm_response.data, 8, False); memset(lm_response.data+8, 0, 16); @@ -580,16 +914,21 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); MD5Final(session_nonce_hash, &md5_session_nonce_ctx); + + DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); + DEBUG(5, ("challenge is: \n")); + dump_data(5, session_nonce_hash, 8); - nt_response = data_blob(NULL, 24); + nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBNTencrypt(ntlmssp_state->password, session_nonce_hash, nt_response.data); - session_key = data_blob(NULL, 16); + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key); hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data); + dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { @@ -600,22 +939,24 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st /* lanman auth is insecure, it may be disabled */ if (lp_client_lanman_auth()) { - lm_response = data_blob(NULL, 24); + lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBencrypt(ntlmssp_state->password,challenge_blob.data, lm_response.data); - } + } - nt_response = data_blob(NULL, 24); + nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, nt_response.data); - session_key = data_blob(NULL, 16); + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && lp_client_lanman_auth()) { SMBsesskeygen_lmv1(lm_hash, lm_response.data, session_key.data); + dump_data_pw("LM session key\n", session_key.data, session_key.length); } else { SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + dump_data_pw("NT session key:\n", session_key.data, session_key.length); } } data_blob_free(&struct_blob); @@ -627,9 +968,12 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st generate_random_buffer(client_session_key, sizeof(client_session_key), False); encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); + dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); + SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); data_blob_free(&session_key); - session_key = data_blob(client_session_key, sizeof(client_session_key)); + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key)); + dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); } /* this generates the actual auth packet */ @@ -644,28 +988,24 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags)) { - data_blob_free(&lm_response); - data_blob_free(&nt_response); - data_blob_free(&session_key); return NT_STATUS_NO_MEMORY; } data_blob_free(&encrypted_session_key); data_blob_free(&ntlmssp_state->chal); - data_blob_free(&ntlmssp_state->lm_resp); - data_blob_free(&ntlmssp_state->nt_resp); - data_blob_free(&ntlmssp_state->session_key); ntlmssp_state->chal = challenge_blob; ntlmssp_state->lm_resp = lm_response; ntlmssp_state->nt_resp = nt_response; ntlmssp_state->session_key = session_key; + ntlmssp_state->expected_state = NTLMSSP_UNKNOWN; + return NT_STATUS_MORE_PROCESSING_REQUIRED; } -NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) +NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) { TALLOC_CTX *mem_ctx; @@ -678,6 +1018,8 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) return NT_STATUS_NO_MEMORY; } + (*ntlmssp_state)->role = NTLMSSP_CLIENT; + (*ntlmssp_state)->mem_ctx = mem_ctx; (*ntlmssp_state)->get_global_myname = global_myname; @@ -687,6 +1029,10 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth(); + (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL; + + (*ntlmssp_state)->ref_count = 1; + (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | @@ -700,101 +1046,6 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_REQUEST_TARGET; - (*ntlmssp_state)->ref_count = 1; - - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - - (*ntlmssp_state)->ref_count--; - - if ((*ntlmssp_state)->ref_count == 0) { - data_blob_free(&(*ntlmssp_state)->chal); - data_blob_free(&(*ntlmssp_state)->lm_resp); - data_blob_free(&(*ntlmssp_state)->nt_resp); - data_blob_free(&(*ntlmssp_state)->session_key); - data_blob_free(&(*ntlmssp_state)->stored_response); - talloc_destroy(mem_ctx); - } - - *ntlmssp_state = NULL; return NT_STATUS_OK; } -NTSTATUS ntlmssp_client_update(NTLMSSP_CLIENT_STATE *ntlmssp_state, - DATA_BLOB reply, DATA_BLOB *next_request) -{ - NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; - uint32 ntlmssp_command; - *next_request = data_blob(NULL, 0); - - if (!reply.length) { - /* If there is a cached reply, use it - otherwise this is the first packet */ - if (!ntlmssp_state->stored_response.length) { - return ntlmssp_client_initial(ntlmssp_state, reply, next_request); - } - - reply = ntlmssp_state->stored_response; - } - - if (!msrpc_parse(&reply, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (ntlmssp_command == NTLMSSP_CHALLENGE) { - nt_status = ntlmssp_client_challenge(ntlmssp_state, reply, next_request); - } - if (ntlmssp_state->stored_response.length) { - data_blob_free(&ntlmssp_state->stored_response); - } - return nt_status; -} - -NTSTATUS ntlmssp_set_username(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *user) -{ - ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); - if (!ntlmssp_state->user) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_set_password(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *password) -{ - if (!password) { - ntlmssp_state->password = NULL; - } else { - ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); - if (!ntlmssp_state->password) { - return NT_STATUS_NO_MEMORY; - } - } - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_set_domain(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *domain) -{ - ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); - if (!ntlmssp_state->domain) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Store a DATA_BLOB containing an NTLMSSP response, for use later. - * This 'keeps' the data blob - the caller must *not* free it. - */ - -NTSTATUS ntlmssp_client_store_response(NTLMSSP_CLIENT_STATE *ntlmssp_state, - DATA_BLOB response) -{ - data_blob_free(&ntlmssp_state->stored_response); - ntlmssp_state->stored_response = response; - return NT_STATUS_OK; -} diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index b136dacf5a..3444db0306 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -31,7 +31,7 @@ format specifiers are: U = unicode string (input is unix string) - a = address (input is BOOL unicode, char *unix_string) + a = address (input is char *unix_string) (1 byte type, 1 byte length, unicode/ASCII string, all inline) A = ASCII string (input is unix string) B = data blob (pointer + length) @@ -49,7 +49,6 @@ BOOL msrpc_gen(DATA_BLOB *blob, uint8 *b; int head_size=0, data_size=0; int head_ofs, data_ofs; - BOOL unicode; /* first scan the format to work out the header and body size */ va_start(ap, format); @@ -66,14 +65,9 @@ BOOL msrpc_gen(DATA_BLOB *blob, data_size += str_ascii_charnum(s); break; case 'a': - unicode = va_arg(ap, BOOL); n = va_arg(ap, int); s = va_arg(ap, char *); - if (unicode) { - data_size += (str_charnum(s) * 2) + 4; - } else { - data_size += (str_ascii_charnum(s)) + 4; - } + data_size += (str_charnum(s) * 2) + 4; break; case 'B': b = va_arg(ap, uint8 *); @@ -124,27 +118,16 @@ BOOL msrpc_gen(DATA_BLOB *blob, data_ofs += n; break; case 'a': - unicode = va_arg(ap, BOOL); n = va_arg(ap, int); SSVAL(blob->data, data_ofs, n); data_ofs += 2; s = va_arg(ap, char *); - if (unicode) { - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); - } - data_ofs += n*2; - } else { - n = str_ascii_charnum(s); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n, - STR_ASCII|STR_NOALIGN); - } - data_ofs += n; + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); } + data_ofs += n*2; break; case 'B': diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 153c234d1f..ea1a7037c9 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -102,7 +102,7 @@ enum ntlmssp_direction { NTLMSSP_RECEIVE }; -static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_state, +static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, const uchar *data, size_t length, enum ntlmssp_direction direction, DATA_BLOB *sig) @@ -113,7 +113,7 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->cli_sign_const), 16, &ctx); + hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); @@ -124,10 +124,10 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat } switch (direction) { case NTLMSSP_SEND: - NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data+4, sig->length-4); + NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); break; case NTLMSSP_RECEIVE: - NTLMSSPcalc_ap(ntlmssp_state->srv_sign_hash, sig->data+4, sig->length-4); + NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); break; } } else { @@ -144,9 +144,9 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat return NT_STATUS_OK; } -NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, - const uchar *data, size_t length, - DATA_BLOB *sig) +NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, + const uchar *data, size_t length, + DATA_BLOB *sig) { NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); @@ -161,9 +161,9 @@ NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, - const uchar *data, size_t length, - const DATA_BLOB *sig) +NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, + const uchar *data, size_t length, + const DATA_BLOB *sig) { DATA_BLOB local_sig; NTSTATUS nt_status; @@ -204,11 +204,11 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, - uchar *data, size_t length, - DATA_BLOB *sig) +NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, + uchar *data, size_t length, + DATA_BLOB *sig) { - DEBUG(10,("ntlmssp_client_seal_data: seal\n")); + DEBUG(10,("ntlmssp_seal_data: seal\n")); dump_data_pw("ntlmssp clear data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; @@ -216,7 +216,7 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->cli_sign_const), 16, &ctx); + hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); @@ -227,13 +227,13 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, } dump_data_pw("ntlmssp client sealing hash:\n", - ntlmssp_state->cli_seal_hash, - sizeof(ntlmssp_state->cli_seal_hash)); - NTLMSSPcalc_ap(ntlmssp_state->cli_seal_hash, data, length); + ntlmssp_state->send_seal_hash, + sizeof(ntlmssp_state->send_seal_hash)); + NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length); dump_data_pw("ntlmssp client signing hash:\n", - ntlmssp_state->cli_sign_hash, - sizeof(ntlmssp_state->cli_sign_hash)); - NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data+4, sig->length-4); + ntlmssp_state->send_sign_hash, + sizeof(ntlmssp_state->send_sign_hash)); + NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); } else { uint32 crc; crc = crc32_calc_buffer((const char *)data, length); @@ -266,14 +266,14 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_client_unseal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, +NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, uchar *data, size_t length, DATA_BLOB *sig) { - DEBUG(10,("ntlmssp_client_unseal_data: seal\n")); + DEBUG(10,("ntlmssp__unseal_data: seal\n")); dump_data_pw("ntlmssp sealed data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - NTLMSSPcalc_ap(ntlmssp_state->srv_seal_hash, data, length); + NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length); } else { dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); @@ -281,13 +281,13 @@ NTSTATUS ntlmssp_client_unseal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, } dump_data_pw("ntlmssp clear data\n", data, length); - return ntlmssp_client_check_packet(ntlmssp_state, data, length, sig); + return ntlmssp_check_packet(ntlmssp_state, data, length, sig); } /** Initialise the state for NTLMSSP signing. */ -NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) +NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) { unsigned char p24[24]; ZERO_STRUCT(p24); @@ -297,34 +297,54 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + const char *send_sign_const; + const char *send_seal_const; + const char *recv_sign_const; + const char *recv_seal_const; + + switch (ntlmssp_state->role) { + case NTLMSSP_CLIENT: + send_sign_const = CLI_SIGN; + send_seal_const = CLI_SEAL; + recv_sign_const = SRV_SIGN; + recv_seal_const = SRV_SEAL; + break; + case NTLMSSP_SERVER: + send_sign_const = SRV_SIGN; + send_seal_const = SRV_SEAL; + recv_sign_const = CLI_SIGN; + recv_seal_const = CLI_SEAL; + break; + } + + calc_ntlmv2_hash(ntlmssp_state->send_sign_hash, + ntlmssp_state->send_sign_const, + ntlmssp_state->session_key, send_sign_const); + dump_data_pw("NTLMSSP send sign hash:\n", + ntlmssp_state->send_sign_hash, + sizeof(ntlmssp_state->send_sign_hash)); + + calc_ntlmv2_hash(ntlmssp_state->send_seal_hash, + ntlmssp_state->send_seal_const, + ntlmssp_state->session_key, send_seal_const); + dump_data_pw("NTLMSSP send sesl hash:\n", + ntlmssp_state->send_seal_hash, + sizeof(ntlmssp_state->send_seal_hash)); + + calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, + ntlmssp_state->recv_sign_const, + ntlmssp_state->session_key, send_sign_const); + dump_data_pw("NTLMSSP receive sign hash:\n", + ntlmssp_state->recv_sign_hash, + sizeof(ntlmssp_state->recv_sign_hash)); + + calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, + ntlmssp_state->recv_seal_const, + ntlmssp_state->session_key, send_seal_const); + dump_data_pw("NTLMSSP receive seal hash:\n", + ntlmssp_state->recv_sign_hash, + sizeof(ntlmssp_state->recv_sign_hash)); - calc_ntlmv2_hash(ntlmssp_state->cli_sign_hash, - ntlmssp_state->cli_sign_const, - ntlmssp_state->session_key, CLI_SIGN); - dump_data_pw("NTLMSSP client sign hash:\n", - ntlmssp_state->cli_sign_hash, - sizeof(ntlmssp_state->cli_sign_hash)); - - calc_ntlmv2_hash(ntlmssp_state->cli_seal_hash, - ntlmssp_state->cli_seal_const, - ntlmssp_state->session_key, CLI_SEAL); - dump_data_pw("NTLMSSP client sesl hash:\n", - ntlmssp_state->cli_seal_hash, - sizeof(ntlmssp_state->cli_seal_hash)); - - calc_ntlmv2_hash(ntlmssp_state->srv_sign_hash, - ntlmssp_state->srv_sign_const, - ntlmssp_state->session_key, SRV_SIGN); - dump_data_pw("NTLMSSP server sign hash:\n", - ntlmssp_state->srv_sign_hash, - sizeof(ntlmssp_state->srv_sign_hash)); - - calc_ntlmv2_hash(ntlmssp_state->srv_seal_hash, - ntlmssp_state->srv_seal_const, - ntlmssp_state->session_key, SRV_SEAL); - dump_data_pw("NTLMSSP server seal hash:\n", - ntlmssp_state->cli_sign_hash, - sizeof(ntlmssp_state->cli_sign_hash)); } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) { diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 91509f0fb8..eec991072d 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -405,11 +405,11 @@ static void simple_free_signing_context(struct smb_sign_info *si) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) +BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response) { struct smb_basic_signing_context *data; - if (!user_session_key) + if (!user_session_key.length) return False; if (!cli_set_smb_signing_common(cli)) { @@ -425,21 +425,23 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ cli->sign_info.signing_context = data; - data->mac_key = data_blob(NULL, response.length + 16); + data->mac_key = data_blob(NULL, response.length + user_session_key.length); - memcpy(&data->mac_key.data[0], user_session_key, 16); + memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); - dump_data(10, (const char *)user_session_key, 16); + dump_data(10, (const char *)user_session_key.data, user_session_key.length); if (response.length) { - memcpy(&data->mac_key.data[16],response.data, response.length); + memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); DEBUG(10, ("cli_simple_set_signing: response_data\n")); dump_data(10, (const char *)response.data, response.length); } else { DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); } + dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); + /* Initialise the sequence number */ data->send_seq_num = 0; @@ -928,11 +930,11 @@ data->send_seq_num = %u\n", Turn on signing from this packet onwards. ************************************************************/ -void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) +void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) { struct smb_basic_signing_context *data; - if (!user_session_key) + if (!user_session_key.length) return; if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { @@ -957,11 +959,13 @@ void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) srv_sign_info.signing_context = data; - data->mac_key = data_blob(NULL, response.length + 16); + data->mac_key = data_blob(NULL, response.length + user_session_key.length); - memcpy(&data->mac_key.data[0], user_session_key, 16); + memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); if (response.length) - memcpy(&data->mac_key.data[16],response.data, response.length); + memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); + + dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); /* Initialise the sequence number */ data->send_seq_num = 0; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index ec31bb5dba..2d02a23394 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -331,9 +331,9 @@ DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, DATA_BLOB names_blob = data_blob(NULL, 0); msrpc_gen(&names_blob, "aaa", - True, NTLMSSP_NAME_TYPE_DOMAIN, domain, - True, NTLMSSP_NAME_TYPE_SERVER, hostname, - True, 0, ""); + NTLMSSP_NAME_TYPE_DOMAIN, domain, + NTLMSSP_NAME_TYPE_SERVER, hostname, + 0, ""); return names_blob; } diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 8513a46f8f..0630403cbc 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -178,10 +178,9 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, result = NT_STATUS_OK; - if (!cli_session_setup_spnego(new_conn->cli, machine_krb5_principal, + if (!NT_STATUS_IS_OK(result = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal, machine_password, - domain)) { - result = cli_nt_error(new_conn->cli); + domain))) { DEBUG(4,("failed kerberos session setup with %s\n", nt_errstr(result))); if (NT_STATUS_IS_OK(result)) result = NT_STATUS_UNSUCCESSFUL; diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index d696428de4..993e7d68ff 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -224,9 +224,15 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) DATA_BLOB lm_resp, nt_resp; if (!state->privileged) { - DEBUG(2, ("winbindd_pam_auth_crap: non-privileged access denied!\n")); + char *error_string = NULL; + DEBUG(2, ("winbindd_pam_auth_crap: non-privileged access denied. !\n")); + DEBUGADD(2, ("winbindd_pam_auth_crap: Ensure permissions on %s are set correctly.\n", + get_winbind_priv_pipe_dir())); /* send a better message than ACCESS_DENIED */ - push_utf8_fstring(state->response.data.auth.error_string, "winbind client not authorized to use winbindd_pam_auth_crap"); + asprintf(&error_string, "winbind client not authorized to use winbindd_pam_auth_crap. Ensure permissions on %s are set correctly.", + get_winbind_priv_pipe_dir()); + push_utf8_fstring(state->response.data.auth.error_string, error_string); + SAFE_FREE(error_string); result = NT_STATUS_ACCESS_DENIED; goto done; } diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 97bc4c65b7..70ac460303 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -654,11 +654,17 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c ZERO_STRUCT(netlogon_sess_key); memcpy(netlogon_sess_key, cli->sess_key, 8); - if (memcmp(zeros, info3->user_sess_key, 16) != 0) + if (memcmp(zeros, info3->user_sess_key, 16) != 0) { SamOEMhash(info3->user_sess_key, netlogon_sess_key, 16); - - if (memcmp(zeros, info3->padding, 16) != 0) + } else { + memset(info3->user_sess_key, '\0', 16); + } + + if (memcmp(zeros, info3->padding, 16) != 0) { SamOEMhash(info3->padding, netlogon_sess_key, 16); + } else { + memset(info3->padding, '\0', 16); + } /* Return results */ diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index fdd9d3c3b1..aca0494dbd 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -264,13 +264,16 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, later use */ DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len); - + BOOL store_ok; + /* save the reply away, for use a little later */ prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len); + store_ok = (NT_STATUS_IS_OK(ntlmssp_store_response(cli->ntlmssp_pipe_state, + ntlmssp_verf))); - return (NT_STATUS_IS_OK(ntlmssp_client_store_response(cli->ntlmssp_pipe_state, - ntlmssp_verf))); + data_blob_free(&ntlmssp_verf); + return store_ok; } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { /* nothing to do here - we don't seem to be able to @@ -307,12 +310,12 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, DEBUG(1, ("Can't unseal - data_len < 0!!\n")); return False; } - nt_status = ntlmssp_client_unseal_packet(cli->ntlmssp_pipe_state, + nt_status = ntlmssp_unseal_packet(cli->ntlmssp_pipe_state, (unsigned char *)reply_data, data_len, &sig); } else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - nt_status = ntlmssp_client_check_packet(cli->ntlmssp_pipe_state, + nt_status = ntlmssp_check_packet(cli->ntlmssp_pipe_state, (const unsigned char *)reply_data, data_len, &sig); } @@ -674,9 +677,9 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, DATA_BLOB request; DEBUG(5, ("Processing NTLMSSP Negotiate\n")); - nt_status = ntlmssp_client_update(cli->ntlmssp_pipe_state, - null_blob, - &request); + nt_status = ntlmssp_update(cli->ntlmssp_pipe_state, + null_blob, + &request); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { @@ -777,9 +780,9 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli, /* The response is picked up from the internal cache, where it was placed by the rpc_auth_pipe() code */ - nt_status = ntlmssp_client_update(cli->ntlmssp_pipe_state, - ntlmssp_null_response, - &ntlmssp_reply); + nt_status = ntlmssp_update(cli->ntlmssp_pipe_state, + ntlmssp_null_response, + &ntlmssp_reply); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { return nt_status; @@ -820,7 +823,7 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli, } if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - nt_status = ntlmssp_client_sign_init(cli->ntlmssp_pipe_state); + nt_status = ntlmssp_sign_init(cli->ntlmssp_pipe_state); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -994,7 +997,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, */ if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { - nt_status = ntlmssp_client_seal_packet(cli->ntlmssp_pipe_state, + nt_status = ntlmssp_seal_packet(cli->ntlmssp_pipe_state, (unsigned char*)prs_data_p(&sec_blob), data_and_padding_size, &sign_blob); @@ -1005,7 +1008,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, } else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - nt_status = ntlmssp_client_sign_packet(cli->ntlmssp_pipe_state, + nt_status = ntlmssp_sign_packet(cli->ntlmssp_pipe_state, (unsigned char*)prs_data_p(&sec_blob), data_and_padding_size, &sign_blob); if (!NT_STATUS_IS_OK(nt_status)) { diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index e5e67f39dc..9bab816b81 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -1341,7 +1341,7 @@ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *user_pol, uint16 switch_value, - uchar sess_key[16], SAM_USERINFO_CTR *ctr) + DATA_BLOB sess_key, SAM_USERINFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_SET_USERINFO q; @@ -1353,6 +1353,11 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, ZERO_STRUCT(q); ZERO_STRUCT(r); + if (sess_key.length != 16) { + DEBUG(1, ("Cannot handle user session key of length [%u]\n", sess_key.length)); + return NT_STATUS_NO_USER_SESSION_KEY; + } + /* Initialise parse structures */ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); @@ -1393,7 +1398,7 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *user_pol, uint16 switch_value, - uchar sess_key[16], SAM_USERINFO_CTR *ctr) + DATA_BLOB sess_key, SAM_USERINFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_SET_USERINFO2 q; @@ -1402,6 +1407,11 @@ NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, DEBUG(10,("cli_samr_set_userinfo2\n")); + if (sess_key.length != 16) { + DEBUG(1, ("Cannot handle user session key of length [%u]\n", sess_key.length)); + return NT_STATUS_NO_USER_SESSION_KEY; + } + ZERO_STRUCT(q); ZERO_STRUCT(r); diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index 3b096e088a..ad0a91e7ea 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -1265,7 +1265,8 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, uint16 logon_count, uint16 bad_pw_count, uint32 num_groups, const DOM_GID *gids, - uint32 user_flgs, uchar sess_key[16], + uint32 user_flgs, uchar nt_session_key[16], + uchar lm_session_key[16], const char *logon_srv, const char *logon_dom, const DOM_SID *dom_sid, const char *other_sids) { @@ -1307,8 +1308,8 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */ usr->user_flgs = user_flgs; - if (sess_key != NULL) - memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key)); + if (nt_session_key != NULL) + memcpy(usr->user_sess_key, nt_session_key, sizeof(usr->user_sess_key)); else memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key)); @@ -1316,6 +1317,10 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, memset((char *)usr->padding, '\0', sizeof(usr->padding)); + if (lm_session_key != NULL) + memcpy(usr->padding, lm_session_key, sizeof(usr->user_sess_key)); + + num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids); usr->num_other_sids = num_other_sids; diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 20adf0c756..1966538362 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -6302,7 +6302,7 @@ NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr, inits a SAM_USERINFO_CTR structure. ********************************************************************/ -void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, uchar * sess_key, +void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, DATA_BLOB sess_key, uint16 switch_value, void *info) { DEBUG(5, ("init_samr_userinfo_ctr\n")); @@ -6312,13 +6312,13 @@ void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, uchar * sess_key, switch (switch_value) { case 0x18: - SamOEMhash(ctr->info.id24->pass, sess_key, 516); - dump_data(100, (char *)sess_key, 16); + SamOEMhash(ctr->info.id24->pass, sess_key.data, 516); + dump_data(100, (char *)sess_key.data, 16); dump_data(100, (char *)ctr->info.id24->pass, 516); break; case 0x17: - SamOEMhash(ctr->info.id23->pass, sess_key, 516); - dump_data(100, (char *)sess_key, 16); + SamOEMhash(ctr->info.id23->pass, sess_key.data, 516); + dump_data(100, (char *)sess_key.data, 16); dump_data(100, (char *)ctr->info.id23->pass, 516); break; default: @@ -6503,7 +6503,7 @@ inits a SAMR_Q_SET_USERINFO structure. ********************************************************************/ void init_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u, - POLICY_HND *hnd, unsigned char sess_key[16], + POLICY_HND *hnd, DATA_BLOB sess_key, uint16 switch_value, void *info) { DEBUG(5, ("init_samr_q_set_userinfo\n")); @@ -6577,7 +6577,7 @@ inits a SAMR_Q_SET_USERINFO2 structure. ********************************************************************/ void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u, - POLICY_HND *hnd, unsigned char sess_key[16], + POLICY_HND *hnd, DATA_BLOB sess_key, uint16 switch_value, SAM_USERINFO_CTR * ctr) { DEBUG(5, ("init_samr_q_set_userinfo2\n")); @@ -6591,9 +6591,9 @@ void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u, switch (switch_value) { case 0x12: - SamOEMhash(ctr->info.id12->lm_pwd, sess_key, 16); - SamOEMhash(ctr->info.id12->nt_pwd, sess_key, 16); - dump_data(100, (char *)sess_key, 16); + SamOEMhash(ctr->info.id12->lm_pwd, sess_key.data, 16); + SamOEMhash(ctr->info.id12->nt_pwd, sess_key.data, 16); + dump_data(100, (char *)sess_key.data, 16); dump_data(100, (char *)ctr->info.id12->lm_pwd, 16); dump_data(100, (char *)ctr->info.id12->nt_pwd, 16); break; diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 5ba3dac669..65ebef8809 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -683,7 +683,8 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * pstring my_name; fstring user_sid_string; fstring group_sid_string; - uchar user_sess_key[16]; + uchar nt_session_key[16]; + uchar lm_session_key[16]; uchar netlogon_sess_key[16]; sampw = server_info->sam_account; @@ -718,10 +719,18 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * ZERO_STRUCT(netlogon_sess_key); memcpy(netlogon_sess_key, p->dc.sess_key, 8); - memcpy(user_sess_key, server_info->session_key, sizeof(user_sess_key)); - SamOEMhash(user_sess_key, netlogon_sess_key, 16); + if (server_info->nt_session_key.length) { + memcpy(nt_session_key, server_info->nt_session_key.data, + MIN(sizeof(nt_session_key), server_info->nt_session_key.length)); + SamOEMhash(nt_session_key, netlogon_sess_key, 16); + } + if (server_info->lm_session_key.length) { + memcpy(lm_session_key, server_info->lm_session_key.data, + MIN(sizeof(lm_session_key), server_info->lm_session_key.length)); + SamOEMhash(lm_session_key, netlogon_sess_key, 16); + } ZERO_STRUCT(netlogon_sess_key); - + init_net_user_info3(p->mem_ctx, usr_info, user_rid, group_rid, @@ -743,14 +752,16 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * num_gids, /* uint32 num_groups */ gids , /* DOM_GID *gids */ 0x20 , /* uint32 user_flgs (?) */ - user_sess_key, + server_info->nt_session_key.length ? nt_session_key : NULL, + server_info->lm_session_key.length ? lm_session_key : NULL, my_name , /* char *logon_srv */ pdb_get_domain(sampw), &domain_sid, /* DOM_SID *dom_sid */ /* Should be users domain sid, not servers - for trusted domains */ NULL); /* char *other_sids */ - ZERO_STRUCT(user_sess_key); + ZERO_STRUCT(nt_session_key); + ZERO_STRUCT(lm_session_key); } free_server_info(&server_info); return status; diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 7bbe726f5a..90c20a97fa 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -420,9 +420,15 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); * Set up the sign/seal data. */ - { + if (server_info->lm_session_key.length != 16) { + DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \ +succeeded authentication on named pipe %s, but session key was of incorrect length [%u].\n", + domain, user_name, wks, p->name, server_info->lm_session_key.length)); + free_server_info(&server_info); + return False; + } else { uchar p24[24]; - NTLMSSPOWFencrypt(server_info->first_8_lm_hash, lm_owf, p24); + NTLMSSPOWFencrypt(server_info->lm_session_key.data, lm_owf, p24); { unsigned char j = 0; int ind; @@ -468,7 +474,7 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ - memcpy(p->session_key, server_info->session_key, sizeof(p->session_key)); + p->session_key = data_blob(server_info->lm_session_key.data, server_info->lm_session_key.length); p->pipe_user.uid = server_info->uid; p->pipe_user.gid = server_info->gid; diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 57e45d477f..a9fd9ec652 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -342,7 +342,7 @@ static void *make_internal_rpc_pipe_p(char *pipe_name, /* Store the session key and NT_TOKEN */ if (vuser) { - memcpy(p->session_key, vuser->session_key, sizeof(p->session_key)); + p->session_key = data_blob(vuser->session_key.data, vuser->session_key.length); p->pipe_user.nt_user_token = dup_nt_token(vuser->nt_user_token); } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 1cfa8b2853..1debf90d23 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2953,7 +2953,13 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE break; case 24: - SamOEMhash(ctr->info.id24->pass, p->session_key, 516); + if (p->session_key.length != 16) { + /* we may have no session key at all, + and we don't know how to do the SamOEMhash + for length != 16 */ + return NT_STATUS_NO_USER_SESSION_KEY; + } + SamOEMhash(ctr->info.id24->pass, p->session_key.data, 516); dump_data(100, (char *)ctr->info.id24->pass, 516); @@ -2971,7 +2977,10 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE * info level and W2K SP2 drops down to level 23... JRA. */ - SamOEMhash(ctr->info.id25->pass, p->session_key, 532); + if (p->session_key.length != 16) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + SamOEMhash(ctr->info.id25->pass, p->session_key.data, 532); dump_data(100, (char *)ctr->info.id25->pass, 532); @@ -2982,7 +2991,10 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE return NT_STATUS_INVALID_INFO_CLASS; case 23: - SamOEMhash(ctr->info.id23->pass, p->session_key, 516); + if (p->session_key.length != 16) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + SamOEMhash(ctr->info.id23->pass, p->session_key.data, 516); dump_data(100, (char *)ctr->info.id23->pass, 516); diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 958ed663e6..494d9ecd43 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -77,6 +77,8 @@ void invalidate_vuid(uint16 vuid) free_server_info(&vuser->server_info); + data_blob_free(&vuser->session_key); + DLIST_REMOVE(validated_users, vuser); /* clear the vuid from the 'cache' on each connection, and @@ -109,25 +111,36 @@ void invalidate_all_vuids(void) * @param server_info The token returned from the authentication process. * (now 'owned' by register_vuid) * + * @param session_key The User session key for the login session (now also 'owned' by register_vuid) + * + * @param respose_blob The NT challenge-response, if available. (May be freed after this call) + * + * @param smb_name The untranslated name of the user + * * @return Newly allocated vuid, biased by an offset. (This allows us to * tell random client vuid's (normally zero) from valid vuids.) * */ -int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob, const char *smb_name) +int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, DATA_BLOB response_blob, const char *smb_name) { user_struct *vuser = NULL; /* Ensure no vuid gets registered in share level security. */ - if(lp_security() == SEC_SHARE) + if(lp_security() == SEC_SHARE) { + data_blob_free(&session_key); return UID_FIELD_INVALID; + } /* Limit allowed vuids to 16bits - VUID_OFFSET. */ - if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) + if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) { + data_blob_free(&session_key); return UID_FIELD_INVALID; + } if((vuser = (user_struct *)malloc( sizeof(user_struct) )) == NULL) { DEBUG(0,("Failed to malloc users struct!\n")); + data_blob_free(&session_key); return UID_FIELD_INVALID; } @@ -156,6 +169,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob if (vuser->n_groups) { if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) { DEBUG(0,("register_vuid: failed to memdup vuser->groups\n")); + data_blob_free(&session_key); free(vuser); free_server_info(&server_info); return UID_FIELD_INVALID; @@ -197,7 +211,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob } } - memcpy(vuser->session_key, server_info->session_key, sizeof(vuser->session_key)); + vuser->session_key = session_key; DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)vuser->uid, @@ -211,6 +225,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob } else { DEBUG(1, ("server_info does not contain a user_token - cannot continue\n")); free_server_info(&server_info); + data_blob_free(&session_key); SAFE_FREE(vuser->homedir); SAFE_FREE(vuser->unix_homedir); SAFE_FREE(vuser->logon_script); diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 314ffbb4a9..64c25db2ab 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -149,7 +149,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB auth_data; DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; - uint8 session_key[16]; + DATA_BLOB session_key; uint8 tok_id[2]; BOOL foreign = False; DATA_BLOB nullblob = data_blob(NULL, 0); @@ -164,7 +164,7 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, session_key); + ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, &session_key); data_blob_free(&ticket); @@ -223,11 +223,8 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(ret); } - /* Copy out the session key from the AP_REQ. */ - memcpy(server_info->session_key, session_key, sizeof(session_key)); - /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, nullblob, user); + sess_vuid = register_vuid(server_info, session_key, nullblob, user); free(user); @@ -297,9 +294,10 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out if (NT_STATUS_IS_OK(nt_status)) { int sess_vuid; DATA_BLOB nullblob = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user); + sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user); (*auth_ntlmssp_state)->server_info = NULL; if (sess_vuid == -1) { @@ -566,6 +564,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, NTSTATUS nt_status; BOOL doencrypt = global_encrypted_passwords_negotiated; + + DATA_BLOB session_key; START_PROFILE(SMBsesssetupX); @@ -766,18 +766,28 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, free_user_info(&user_info); - data_blob_free(&lm_resp); - data_blob_clear_free(&plaintext_password); - if (!NT_STATUS_IS_OK(nt_status)) { nt_status = do_map_to_guest(nt_status, &server_info, user, domain); } if (!NT_STATUS_IS_OK(nt_status)) { data_blob_free(&nt_resp); + data_blob_free(&lm_resp); + data_blob_clear_free(&plaintext_password); return ERROR_NT(nt_status_squash(nt_status)); } + if (server_info->nt_session_key.data) { + session_key = data_blob(server_info->nt_session_key.data, server_info->nt_session_key.length); + } else if (server_info->lm_session_key.length >= 8 && lm_resp.length == 24) { + session_key = data_blob(NULL, 16); + SMBsesskeygen_lmv1(server_info->lm_session_key.data, lm_resp.data, + session_key.data); + } + + data_blob_free(&lm_resp); + data_blob_clear_free(&plaintext_password); + /* it's ok - setup a reply */ set_message(outbuf,3,0,True); if (Protocol >= PROTOCOL_NT1) { @@ -795,7 +805,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, to a uid can get through without a password, on the same VC */ /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, nt_resp, sub_user); + sess_vuid = register_vuid(server_info, session_key, nt_resp, sub_user); data_blob_free(&nt_resp); if (sess_vuid == -1) { diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 7cd7e0b087..5b1b83d032 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -29,14 +29,42 @@ #define SQUID_BUFFER_SIZE 2010 -enum squid_mode { +enum stdio_helper_mode { SQUID_2_4_BASIC, SQUID_2_5_BASIC, SQUID_2_5_NTLMSSP, GSS_SPNEGO, - GSS_SPNEGO_CLIENT + GSS_SPNEGO_CLIENT, + NUM_HELPER_MODES +}; + +typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode, + char *buf, int length); + +static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode, + char *buf, int length); + +static void manage_squid_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, + char *buf, int length); + +static void manage_gss_spnego_request (enum stdio_helper_mode stdio_helper_mode, + char *buf, int length); + +static void manage_gss_spnego_client_request (enum stdio_helper_mode stdio_helper_mode, + char *buf, int length); + +static const struct { + enum stdio_helper_mode mode; + const char *name; + stdio_helper_function fn; +} stdio_helper_protocols[] = { + { SQUID_2_4_BASIC, "squid-2.4-basic", manage_squid_basic_request}, + { SQUID_2_5_BASIC, "squid-2.5-basic", manage_squid_basic_request}, + { SQUID_2_5_NTLMSSP, "squid-2.5-ntlmssp", manage_squid_ntlmssp_request}, + { GSS_SPNEGO, "gss-spnego", manage_gss_spnego_request}, + { GSS_SPNEGO_CLIENT, "gss-spnego-client", manage_gss_spnego_client_request}, + { NUM_HELPER_MODES, NULL, NULL} }; - extern int winbindd_fd; @@ -96,7 +124,7 @@ static const char *get_winbind_domain(void) if (winbindd_request(WINBINDD_DOMAIN_NAME, NULL, &response) != NSS_STATUS_SUCCESS) { - d_printf("could not obtain winbind domain name!\n"); + DEBUG(0, ("could not obtain winbind domain name!\n")); return NULL; } @@ -122,7 +150,7 @@ static const char *get_winbind_netbios_name(void) if (winbindd_request(WINBINDD_NETBIOS_NAME, NULL, &response) != NSS_STATUS_SUCCESS) { - d_printf("could not obtain winbind netbios name!\n"); + DEBUG(0, ("could not obtain winbind netbios name!\n")); return NULL; } @@ -264,20 +292,42 @@ static NTSTATUS contact_winbind_auth_crap(const char *username, return nt_status; } -static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state) +static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key) { - return contact_winbind_auth_crap(ntlmssp_state->user, ntlmssp_state->domain, - ntlmssp_state->workstation, - &ntlmssp_state->chal, - &ntlmssp_state->lm_resp, - &ntlmssp_state->nt_resp, - 0, - NULL, - NULL, - NULL); + static const char zeros[16]; + NTSTATUS nt_status; + char *error_string; + uint8 lm_key[8]; + uint8 nt_key[16]; + + nt_status = contact_winbind_auth_crap(ntlmssp_state->user, ntlmssp_state->domain, + ntlmssp_state->workstation, + &ntlmssp_state->chal, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + WBFLAG_PAM_LMKEY | WBFLAG_PAM_NTKEY, + lm_key, nt_key, + &error_string); + + if (NT_STATUS_IS_OK(nt_status)) { + if (memcmp(lm_key, zeros, 8) != 0) { + *lm_session_key = data_blob(NULL, 16); + memcpy(lm_session_key->data, lm_key, 8); + memset(lm_session_key->data+8, '\0', 8); + } + + if (memcmp(nt_key, zeros, 16) != 0) { + *nt_session_key = data_blob(nt_key, 16); + } + } else { + DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3, + ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", + ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation, error_string ? error_string : "unknown error (NULL)")); + } + return nt_status; } -static void manage_squid_ntlmssp_request(enum squid_mode squid_mode, +static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; @@ -295,7 +345,7 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode, } else if (strcmp(buf, "YR") == 0) { request = data_blob(NULL, 0); if (ntlmssp_state) - ntlmssp_server_end(&ntlmssp_state); + ntlmssp_end(&ntlmssp_state); } else { DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); @@ -312,7 +362,7 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode, DEBUG(10, ("got NTLMSSP packet:\n")); dump_data(10, (const char *)request.data, request.length); - nt_status = ntlmssp_server_update(ntlmssp_state, request, &reply); + nt_status = ntlmssp_update(ntlmssp_state, request, &reply); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { char *reply_base64 = base64_encode_data_blob(reply); @@ -320,6 +370,9 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode, SAFE_FREE(reply_base64); data_blob_free(&reply); DEBUG(10, ("NTLMSSP challenge\n")); + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { + x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); + DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); } else if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status)); DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status))); @@ -331,7 +384,7 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode, data_blob_free(&request); } -static void manage_squid_basic_request(enum squid_mode squid_mode, +static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { char *user, *pass; @@ -346,7 +399,7 @@ static void manage_squid_basic_request(enum squid_mode squid_mode, *pass='\0'; pass++; - if (squid_mode == SQUID_2_5_BASIC) { + if (stdio_helper_mode == SQUID_2_5_BASIC) { rfc1738_unescape(user); rfc1738_unescape(pass); } @@ -409,7 +462,7 @@ static void offer_gss_spnego_mechs(void) { return; } -static void manage_gss_spnego_request(enum squid_mode squid_mode, +static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; @@ -470,9 +523,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode, if (request.type == SPNEGO_NEG_TOKEN_INIT) { /* Second request from Client. This is where the - client offers its mechanism to use. We currently - only support NTLMSSP, the decision for Kerberos - would be taken here. */ + client offers its mechanism to use. */ if ( (request.negTokenInit.mechTypes == NULL) || (request.negTokenInit.mechTypes[0] == NULL) ) { @@ -493,7 +544,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode, DEBUG(1, ("Client wants a new NTLMSSP challenge, but " "already got one\n")); x_fprintf(x_stdout, "BH\n"); - ntlmssp_server_end(&ntlmssp_state); + ntlmssp_end(&ntlmssp_state); return; } @@ -510,7 +561,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode, response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP); response.negTokenTarg.mechListMIC = data_blob(NULL, 0); - status = ntlmssp_server_update(ntlmssp_state, + status = ntlmssp_update(ntlmssp_state, request.negTokenInit.mechToken, &response.negTokenTarg.responseToken); } @@ -521,7 +572,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode, char *principal; DATA_BLOB auth_data; DATA_BLOB ap_rep; - uint8 session_key[16]; + DATA_BLOB session_key; if ( request.negTokenInit.mechToken.data == NULL ) { DEBUG(1, ("Client did not provide Kerberos data\n")); @@ -537,7 +588,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode, status = ads_verify_ticket(lp_realm(), &request.negTokenInit.mechToken, &principal, &auth_data, &ap_rep, - session_key); + &session_key); /* Now in "principal" we have the name we are authenticated as. */ @@ -583,7 +634,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode, return; } - status = ntlmssp_server_update(ntlmssp_state, + status = ntlmssp_update(ntlmssp_state, request.negTokenTarg.responseToken, &response.negTokenTarg.responseToken); @@ -594,7 +645,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode, if (NT_STATUS_IS_OK(status)) { user = strdup(ntlmssp_state->user); domain = strdup(ntlmssp_state->domain); - ntlmssp_server_end(&ntlmssp_state); + ntlmssp_end(&ntlmssp_state); } } @@ -638,7 +689,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode, return; } -static NTLMSSP_CLIENT_STATE *client_ntlmssp_state = NULL; +static NTLMSSP_STATE *client_ntlmssp_state = NULL; static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego) { @@ -677,7 +728,7 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego) if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not start NTLMSSP client: %s\n", nt_errstr(status))); - ntlmssp_client_end(&client_ntlmssp_state); + ntlmssp_end(&client_ntlmssp_state); return False; } @@ -686,7 +737,7 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego) if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set username: %s\n", nt_errstr(status))); - ntlmssp_client_end(&client_ntlmssp_state); + ntlmssp_end(&client_ntlmssp_state); return False; } @@ -695,7 +746,7 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego) if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set domain: %s\n", nt_errstr(status))); - ntlmssp_client_end(&client_ntlmssp_state); + ntlmssp_end(&client_ntlmssp_state); return False; } @@ -704,7 +755,7 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego) if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set password: %s\n", nt_errstr(status))); - ntlmssp_client_end(&client_ntlmssp_state); + ntlmssp_end(&client_ntlmssp_state); return False; } @@ -713,13 +764,13 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego) spnego.negTokenInit.reqFlags = 0; spnego.negTokenInit.mechListMIC = null_blob; - status = ntlmssp_client_update(client_ntlmssp_state, null_blob, + status = ntlmssp_update(client_ntlmssp_state, null_blob, &spnego.negTokenInit.mechToken); if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED, got: %s\n", nt_errstr(status))); - ntlmssp_client_end(&client_ntlmssp_state); + ntlmssp_end(&client_ntlmssp_state); return False; } @@ -746,23 +797,23 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego) if (client_ntlmssp_state == NULL) { DEBUG(1, ("Got NTLMSSP tArg without a client state\n")); x_fprintf(x_stdout, "BH\n"); - ntlmssp_client_end(&client_ntlmssp_state); + ntlmssp_end(&client_ntlmssp_state); return; } if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { x_fprintf(x_stdout, "NA\n"); - ntlmssp_client_end(&client_ntlmssp_state); + ntlmssp_end(&client_ntlmssp_state); return; } if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) { x_fprintf(x_stdout, "AF\n"); - ntlmssp_client_end(&client_ntlmssp_state); + ntlmssp_end(&client_ntlmssp_state); return; } - status = ntlmssp_client_update(client_ntlmssp_state, + status = ntlmssp_update(client_ntlmssp_state, spnego.negTokenTarg.responseToken, &request); @@ -772,7 +823,7 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego) nt_errstr(status))); x_fprintf(x_stdout, "BH\n"); data_blob_free(&request); - ntlmssp_client_end(&client_ntlmssp_state); + ntlmssp_end(&client_ntlmssp_state); return; } @@ -798,7 +849,7 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego) { char *principal; DATA_BLOB tkt, to_server; - unsigned char session_key_krb5[16]; + DATA_BLOB session_key_krb5; SPNEGO_DATA reply; char *reply_base64; @@ -822,7 +873,7 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego) spnego.negTokenInit.mechListMIC.length); principal[spnego.negTokenInit.mechListMIC.length] = '\0'; - tkt = cli_krb5_get_ticket(principal, 0, session_key_krb5); + tkt = cli_krb5_get_ticket(principal, 0, &session_key_krb5); if (tkt.data == NULL) { @@ -845,9 +896,11 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego) return True; } - tkt = cli_krb5_get_ticket(principal, 0, session_key_krb5); + tkt = cli_krb5_get_ticket(principal, 0, &session_key_krb5); } + data_blob_free(&session_key_krb5); + ZERO_STRUCT(reply); reply.type = SPNEGO_NEG_TOKEN_INIT; @@ -896,7 +949,7 @@ static void manage_client_krb5_targ(SPNEGO_DATA spnego) #endif -static void manage_gss_spnego_client_request(enum squid_mode squid_mode, +static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { DATA_BLOB request; @@ -1000,7 +1053,7 @@ static void manage_gss_spnego_client_request(enum squid_mode squid_mode, x_fprintf(x_stdout, "BH\n"); } - ntlmssp_client_end(&client_ntlmssp_state); + ntlmssp_end(&client_ntlmssp_state); goto out; } @@ -1029,7 +1082,7 @@ static void manage_gss_spnego_client_request(enum squid_mode squid_mode, return; } -static void manage_squid_request(enum squid_mode squid_mode) +static void manage_squid_request(enum stdio_helper_mode helper_mode, stdio_helper_function fn) { char buf[SQUID_BUFFER_SIZE+1]; int length; @@ -1066,24 +1119,16 @@ static void manage_squid_request(enum squid_mode squid_mode) return; } - if (squid_mode == SQUID_2_5_BASIC || squid_mode == SQUID_2_4_BASIC) { - manage_squid_basic_request(squid_mode, buf, length); - } else if (squid_mode == SQUID_2_5_NTLMSSP) { - manage_squid_ntlmssp_request(squid_mode, buf, length); - } else if (squid_mode == GSS_SPNEGO) { - manage_gss_spnego_request(squid_mode, buf, length); - } else if (squid_mode == GSS_SPNEGO_CLIENT) { - manage_gss_spnego_client_request(squid_mode, buf, length); - } + fn(helper_mode, buf, length); } -static void squid_stream(enum squid_mode squid_mode) { +static void squid_stream(enum stdio_helper_mode stdio_mode, stdio_helper_function fn) { /* initialize FDescs */ x_setbuf(x_stdout, NULL); x_setbuf(x_stderr, NULL); while(1) { - manage_squid_request(squid_mode); + manage_squid_request(stdio_mode, fn); } } @@ -2019,20 +2064,15 @@ enum { } if (helper_protocol) { - if (strcmp(helper_protocol, "squid-2.5-ntlmssp")== 0) { - squid_stream(SQUID_2_5_NTLMSSP); - } else if (strcmp(helper_protocol, "squid-2.5-basic")== 0) { - squid_stream(SQUID_2_5_BASIC); - } else if (strcmp(helper_protocol, "squid-2.4-basic")== 0) { - squid_stream(SQUID_2_4_BASIC); - } else if (strcmp(helper_protocol, "gss-spnego")== 0) { - squid_stream(GSS_SPNEGO); - } else if (strcmp(helper_protocol, "gss-spnego-client") == 0) { - squid_stream(GSS_SPNEGO_CLIENT); - } else { - x_fprintf(x_stderr, "unknown helper protocol [%s]\n", helper_protocol); - exit(1); + int i; + for (i=0; i Date: Sun, 23 Nov 2003 00:22:17 +0000 Subject: Merge from 3.0: Add support for variable-length session keys in our client code. This means that we now support 'net rpc join' with KRB5 (des based) logins. Now, you need to hack 'net' to do that, but the principal is important... When we add kerberos to 'net rpc', it should be possible to still do user management and the like over RPC. - Add server-side support for variable-length session keys (as used by DES based krb5 logins). Andrew Bartlett (This used to be commit 1287cf5f921327c9ea758de46220c4e2dedc485c) --- source3/libsmb/smbdes.c | 40 ++++++++++++++++++++++++++++++++++++++++ source3/rpc_client/cli_samr.c | 12 ++++++------ source3/rpc_parse/parse_samr.c | 22 +++++++++++----------- source3/rpc_server/srv_samr_nt.c | 15 ++++++--------- source3/utils/net_rpc.c | 2 +- source3/utils/net_rpc_join.c | 8 ++++---- 6 files changed, 68 insertions(+), 31 deletions(-) diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index cde77f94a3..ae946b4a66 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -397,6 +397,46 @@ void SamOEMhash( unsigned char *data, const unsigned char *key, int val) } } +void SamOEMhashBlob( unsigned char *data, int len, DATA_BLOB *key) +{ + unsigned char s_box[256]; + unsigned char index_i = 0; + unsigned char index_j = 0; + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + s_box[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (s_box[ind] + key->data[ind%key->length]); + + tc = s_box[ind]; + s_box[ind] = s_box[j]; + s_box[j] = tc; + } + for( ind = 0; ind < len; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += s_box[index_i]; + + tc = s_box[index_i]; + s_box[index_i] = s_box[index_j]; + s_box[index_j] = tc; + + t = s_box[index_i] + s_box[index_j]; + data[ind] = data[ind] ^ s_box[t]; + } +} + /* Decode a sam password hash into a password. The password hash is the same method used to store passwords in the NT registry. The DES key used is based on the RID of the user. */ diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 9bab816b81..0eebcd0a6f 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -1341,7 +1341,7 @@ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *user_pol, uint16 switch_value, - DATA_BLOB sess_key, SAM_USERINFO_CTR *ctr) + DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_SET_USERINFO q; @@ -1353,8 +1353,8 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, ZERO_STRUCT(q); ZERO_STRUCT(r); - if (sess_key.length != 16) { - DEBUG(1, ("Cannot handle user session key of length [%u]\n", sess_key.length)); + if (!sess_key->length) { + DEBUG(1, ("No user session key\n")); return NT_STATUS_NO_USER_SESSION_KEY; } @@ -1398,7 +1398,7 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *user_pol, uint16 switch_value, - DATA_BLOB sess_key, SAM_USERINFO_CTR *ctr) + DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_SET_USERINFO2 q; @@ -1407,8 +1407,8 @@ NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, DEBUG(10,("cli_samr_set_userinfo2\n")); - if (sess_key.length != 16) { - DEBUG(1, ("Cannot handle user session key of length [%u]\n", sess_key.length)); + if (!sess_key->length) { + DEBUG(1, ("No user session key\n")); return NT_STATUS_NO_USER_SESSION_KEY; } diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 1966538362..5e3502b242 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -6302,8 +6302,8 @@ NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr, inits a SAM_USERINFO_CTR structure. ********************************************************************/ -void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, DATA_BLOB sess_key, - uint16 switch_value, void *info) +static void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, DATA_BLOB *sess_key, + uint16 switch_value, void *info) { DEBUG(5, ("init_samr_userinfo_ctr\n")); @@ -6312,13 +6312,13 @@ void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, DATA_BLOB sess_key, switch (switch_value) { case 0x18: - SamOEMhash(ctr->info.id24->pass, sess_key.data, 516); - dump_data(100, (char *)sess_key.data, 16); + SamOEMhashBlob(ctr->info.id24->pass, 516, sess_key); + dump_data(100, (char *)sess_key->data, sess_key->length); dump_data(100, (char *)ctr->info.id24->pass, 516); break; case 0x17: - SamOEMhash(ctr->info.id23->pass, sess_key.data, 516); - dump_data(100, (char *)sess_key.data, 16); + SamOEMhashBlob(ctr->info.id23->pass, 516, sess_key); + dump_data(100, (char *)sess_key->data, sess_key->length); dump_data(100, (char *)ctr->info.id23->pass, 516); break; default: @@ -6503,7 +6503,7 @@ inits a SAMR_Q_SET_USERINFO structure. ********************************************************************/ void init_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u, - POLICY_HND *hnd, DATA_BLOB sess_key, + POLICY_HND *hnd, DATA_BLOB *sess_key, uint16 switch_value, void *info) { DEBUG(5, ("init_samr_q_set_userinfo\n")); @@ -6577,7 +6577,7 @@ inits a SAMR_Q_SET_USERINFO2 structure. ********************************************************************/ void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u, - POLICY_HND *hnd, DATA_BLOB sess_key, + POLICY_HND *hnd, DATA_BLOB *sess_key, uint16 switch_value, SAM_USERINFO_CTR * ctr) { DEBUG(5, ("init_samr_q_set_userinfo2\n")); @@ -6591,9 +6591,9 @@ void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u, switch (switch_value) { case 0x12: - SamOEMhash(ctr->info.id12->lm_pwd, sess_key.data, 16); - SamOEMhash(ctr->info.id12->nt_pwd, sess_key.data, 16); - dump_data(100, (char *)sess_key.data, 16); + SamOEMhashBlob(ctr->info.id12->lm_pwd, 16, sess_key); + SamOEMhashBlob(ctr->info.id12->nt_pwd, 16, sess_key); + dump_data(100, (char *)sess_key->data, sess_key->length); dump_data(100, (char *)ctr->info.id12->lm_pwd, 16); dump_data(100, (char *)ctr->info.id12->nt_pwd, 16); break; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 1debf90d23..6cd5da4892 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2953,13 +2953,10 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE break; case 24: - if (p->session_key.length != 16) { - /* we may have no session key at all, - and we don't know how to do the SamOEMhash - for length != 16 */ + if (!p->session_key.length) { return NT_STATUS_NO_USER_SESSION_KEY; } - SamOEMhash(ctr->info.id24->pass, p->session_key.data, 516); + SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key); dump_data(100, (char *)ctr->info.id24->pass, 516); @@ -2977,10 +2974,10 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE * info level and W2K SP2 drops down to level 23... JRA. */ - if (p->session_key.length != 16) { + if (!p->session_key.length) { return NT_STATUS_NO_USER_SESSION_KEY; } - SamOEMhash(ctr->info.id25->pass, p->session_key.data, 532); + SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key); dump_data(100, (char *)ctr->info.id25->pass, 532); @@ -2991,10 +2988,10 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE return NT_STATUS_INVALID_INFO_CLASS; case 23: - if (p->session_key.length != 16) { + if (!p->session_key.length) { return NT_STATUS_NO_USER_SESSION_KEY; } - SamOEMhash(ctr->info.id23->pass, p->session_key.data, 516); + SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key); dump_data(100, (char *)ctr->info.id23->pass, 516); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 298e8ff669..747fc63e23 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1727,7 +1727,7 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli ctr.info.id24 = &p24; result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24, - cli->user_session_key, &ctr); + &cli->user_session_key, &ctr); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("Could not set trust account password: %s\n", diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index 22ed49c74f..96943468ad 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -70,7 +70,7 @@ int net_rpc_join_ok(const char *domain) /* ensure that schannel uses the right domain */ fstrcpy(cli->domain, domain); if (! NT_STATUS_IS_OK(result = cli_nt_establish_netlogon(cli, channel, stored_md4_trust_password))) { - DEBUG(0,("Error in domain join verfication\n")); + DEBUG(0,("Error in domain join verfication (fresh connection)\n")); goto done; } @@ -282,7 +282,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) ctr.info.id24 = &p24; CHECK_RPC_ERR(cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24, - cli->user_session_key, &ctr), + &cli->user_session_key, &ctr), "error setting trust account password"); /* Why do we have to try to (re-)set the ACB to be the same as what @@ -304,7 +304,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) as a normal user with "Add workstation to domain" privilege. */ result = cli_samr_set_userinfo2(cli, mem_ctx, &user_pol, 0x10, - cli->user_session_key, &ctr); + &cli->user_session_key, &ctr); /* Now check the whole process from top-to-bottom */ cli_samr_close(cli, mem_ctx, &user_pol); @@ -322,7 +322,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) md4_trust_password); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0, ("Error domain join verification: %s\n\n", + DEBUG(0, ("Error domain join verification (reused connection): %s\n\n", nt_errstr(result))); if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) && -- cgit From 8ade0cf1b6eba966fdb3f2544a83c979195cef75 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 23 Nov 2003 00:23:26 +0000 Subject: (Merge from 3.0) Patch by emil@disksites.com to ensure we always always free() each auth method. (We had relied on the use of talloc() only, despite providing the free() callback) Andrew Bartlett (This used to be commit 58c4963a8389dff4d925548217fabed1c9932abd) --- source3/auth/auth.c | 15 +++++++++++++-- source3/auth/auth_server.c | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/source3/auth/auth.c b/source3/auth/auth.c index 20dccc6592..1b49699fbc 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -321,9 +321,20 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, static void free_auth_context(struct auth_context **auth_context) { - if (*auth_context != NULL) + auth_methods *auth_method; + + if (*auth_context) { + /* Free private data of context's authentication methods */ + for (auth_method = (*auth_context)->auth_method_list; auth_method; auth_method = auth_method->next) { + if (auth_method->free_private_data) { + auth_method->free_private_data (&auth_method->private_data); + auth_method->private_data = NULL; + } + } + talloc_destroy((*auth_context)->mem_ctx); - *auth_context = NULL; + *auth_context = NULL; + } } /*************************************************************************** diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c index b57293943c..41adc21784 100644 --- a/source3/auth/auth_server.c +++ b/source3/auth/auth_server.c @@ -143,8 +143,10 @@ static void free_server_private_data(void **private_data_pointer) { struct cli_state **cli = (struct cli_state **)private_data_pointer; if (*cli && (*cli)->initialised) { + DEBUG(10, ("Shutting down smbserver connection\n")); cli_shutdown(*cli); } + *private_data_pointer = NULL; } /**************************************************************************** -- cgit From f5ee9c7b02d6acf02d8e516c6e258965a029dd79 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 24 Nov 2003 17:33:15 +0000 Subject: more access fixes for group enumeration in LDAP; bug 281 (This used to be commit c4ce92e80688fe7fd4b2fde2c31e94baf3e4dca0) --- source3/groupdb/mapping.c | 8 +++++++- source3/passdb/passdb.c | 17 ++++++++++++++--- source3/rpc_server/srv_lsa_nt.c | 9 ++++++++- source3/rpc_server/srv_samr_nt.c | 8 +++++--- source3/rpc_server/srv_util.c | 15 +++++++++++---- source3/smbd/lanman.c | 9 +++++++-- 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 7a07b5c344..8f534d779e 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -629,6 +629,7 @@ Returns a GROUP_MAP struct based on the gid. BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) { struct group *grp; + BOOL ret; if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping")); @@ -641,7 +642,12 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) /* * make a group map from scratch if doesn't exist. */ - if (!pdb_getgrgid(map, gid)) { + + become_root(); + ret = pdb_getgrgid(map, gid); + unbecome_root(); + + if ( !ret ) { map->gid=gid; map->sid_name_use=SID_NAME_ALIAS; diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 7ac8d12198..82b1f9a0eb 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -416,6 +416,7 @@ NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd) { const char *guest_account = lp_guestaccount(); GROUP_MAP map; + BOOL ret; if (!account_data || !pwd) { return NT_STATUS_INVALID_PARAMETER; @@ -445,7 +446,11 @@ NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd) } /* call the mapping code here */ - if(pdb_getgrgid(&map, pwd->pw_gid)) { + become_root(); + ret = pdb_getgrgid(&map, pwd->pw_gid); + unbecome_root(); + + if( ret ) { if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){ DEBUG(0,("Can't set Group SID!\n")); return NT_STATUS_INVALID_PARAMETER; @@ -850,6 +855,8 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi return False; } + /* BEGIN ROOT BLOCK */ + become_root(); if (pdb_getsampwnam(sam_account, user)) { unbecome_root(); @@ -859,7 +866,6 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi pdb_free_sam(&sam_account); return True; } - unbecome_root(); pdb_free_sam(&sam_account); @@ -875,8 +881,10 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi } else { /* it's not a mapped group */ grp = getgrnam(user); - if(!grp) + if(!grp) { + unbecome_root(); /* ---> exit form block */ return False; + } /* *check if it's mapped, if it is reply it doesn't exist @@ -891,12 +899,15 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi */ if (pdb_getgrgid(&map, grp->gr_gid)){ + unbecome_root(); /* ---> exit form block */ return False; } sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid)); *psid_name_use = SID_NAME_ALIAS; } + unbecome_root(); + /* END ROOT BLOCK */ sid_copy( psid, &local_sid); diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index db5c8c83b0..8785cce789 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -845,6 +845,7 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU int num_entries=0; LSA_SID_ENUM *sids=&r_u->sids; int i=0,j=0; + BOOL ret; if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) return NT_STATUS_INVALID_HANDLE; @@ -858,8 +859,14 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU return NT_STATUS_ACCESS_DENIED; /* get the list of mapped groups (domain, local, builtin) */ - if(!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED)) + become_root(); + ret = pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED); + unbecome_root(); + if( !ret ) { + DEBUG(3,("_lsa_enum_accounts: enumeration of groups failed!\n")); return NT_STATUS_OK; + } + if (q_u->enum_context >= num_entries) return NT_STATUS_NO_MORE_ENTRIES; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 6cd5da4892..d3da830991 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -292,6 +292,7 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid) uint32 group_entries = 0; uint32 i; TALLOC_CTX *mem_ctx = info->mem_ctx; + BOOL ret; DEBUG(10,("load_group_domain_entries\n")); @@ -303,13 +304,14 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid) become_root(); - - if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED)) { + ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED); + unbecome_root(); + + if ( !ret ) { DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n")); return NT_STATUS_NO_MEMORY; } - unbecome_root(); info->disp_info.num_group_account=group_entries; diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index 632d381503..d5b87b7c10 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -281,6 +281,7 @@ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SA fstring user_name; uint32 grid; uint32 tmp_rid; + BOOL ret; *numgroups= 0; @@ -290,15 +291,21 @@ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SA DEBUG(10,("get_domain_user_groups: searching domain groups [%s] is a member of\n", user_name)); /* we must wrap this is become/unbecome root for ldap backends */ + become_root(); - /* first get the list of the domain groups */ - if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED)) + ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED); + + unbecome_root(); + + /* end wrapper for group enumeration */ + + + if ( !ret ) return False; + DEBUG(10,("get_domain_user_groups: there are %d mapped groups\n", num_entries)); - unbecome_root(); - /* end wrapper for group enumeration */ /* * alloc memory. In the worse case, we alloc memory for nothing. diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 3ea6ab483b..c53889a7a4 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -1635,6 +1635,7 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c char *str1 = param+2; char *str2 = skip_string(str1,1); char *p = skip_string(str2,1); + BOOL ret; GROUP_MAP *group_list; int num_entries; @@ -1653,8 +1654,12 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c return False; /* get list of domain groups SID_DOMAIN_GRP=2 */ - if(!pdb_enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False)) { - DEBUG(3,("api_RNetGroupEnum:failed to get group list")); + become_root(); + ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False); + unbecome_root(); + + if( !ret ) { + DEBUG(3,("api_RNetGroupEnum:failed to get group list")); return False; } -- cgit From 3500dfdcdc4b0e1a1f5071597fff98369dc122d0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 24 Nov 2003 18:38:15 +0000 Subject: patch from Matthias Hilbig for bug 467; use the dns name (or IP) as the originating client name when using CUPS (This used to be commit eae48cda0f7f1346cd66d5a581c1273880f214d4) --- source3/printing/print_cups.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index 7cf21c966e..291028b70c 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -680,7 +680,7 @@ cups_job_submit(int snum, struct printjob *pjob) *response; /* IPP Response */ cups_lang_t *language; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ - + char *clientname; /* hostname of client for job-originating-host attribute */ DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); @@ -734,9 +734,14 @@ cups_job_submit(int snum, struct printjob *pjob) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pjob->user); + clientname = client_name(); + if (strcmp(clientname, "UNKNOWN") == 0) { + clientname = client_addr(); + } + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-originating-host-name", NULL, - get_remote_machine_name()); + clientname); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, pjob->jobname); -- cgit From 9ce8270a8699e36e81fbb02666e24c57454de7e3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Nov 2003 20:18:44 +0000 Subject: Added "passwd chat timeout" parameter. Docs to follow. Jeremy. (This used to be commit 4d49fb806db6868f97069a603a28a85dc31cfe21) --- source3/param/loadparm.c | 4 ++++ source3/smbd/chgpasswd.c | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index b124c6fd3b..949fc0237c 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -264,6 +264,7 @@ typedef struct BOOL bPamPasswordChange; BOOL bUnixPasswdSync; BOOL bPasswdChatDebug; + int iPasswdChatTimeout; BOOL bTimestampLogs; BOOL bNTSmbSupport; BOOL bNTPipeSupport; @@ -801,6 +802,7 @@ static struct parm_struct parm_table[] = { {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED}, {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED}, {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED}, + {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED}, {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED}, {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED}, {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED}, @@ -1418,6 +1420,7 @@ static void init_globals(void) Globals.bUnixPasswdSync = False; Globals.bPamPasswordChange = False; Globals.bPasswdChatDebug = False; + Globals.iPasswdChatTimeout = 2; /* 2 second default. */ Globals.bUnicode = True; /* Do unicode on the wire by default */ Globals.bNTPipeSupport = True; /* Do NT pipes by default. */ Globals.bNTStatusSupport = True; /* Use NT status by default. */ @@ -1734,6 +1737,7 @@ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly) FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange) FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync) FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug) +FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout) FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode) FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport) FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport) diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index d99570ff7c..5caf78e41a 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -245,7 +245,8 @@ static int expect(int master, char *issue, char *expected) if (strequal(expected, ".")) return True; - timeout = 2000; + /* Initial timeout. */ + timeout = lp_passwd_chat_timeout() * 1000; nread = 0; buffer[nread] = 0; @@ -261,8 +262,10 @@ static int expect(int master, char *issue, char *expected) pstrcpy( str, buffer); trim_char( str, ' ', ' '); - if ((match = (unix_wild_match(expected, str) == 0))) - timeout = 200; + if ((match = (unix_wild_match(expected, str) == 0))) { + /* Now data has started to return, lower timeout. */ + timeout = lp_passwd_chat_timeout() * 100; + } } } -- cgit From f7bf71a34cd2f2465bf4d9e586688bda5c6700f7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 24 Nov 2003 20:22:41 +0000 Subject: strequal() returns a BOOL, not an int like strcmp(); this fixes a bug in check_bind_response() (This used to be commit 84f0e97e5882375b765b818e89a6d96736cd5932) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index aca0494dbd..7517777920 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1234,8 +1234,8 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC if ( hdr_ba->addr.len <= 0) return False; - if ( (strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) != 0) && - (strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) != 0) ) + if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) && + !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) ) { DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n", pipe_names[i].server_pipe ,hdr_ba->addr.str)); -- cgit From b7937e569ce55605e2a837b9ee3144bca4099bc2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Nov 2003 00:32:48 +0000 Subject: When server signing is set to "auto", if the client doesn't sign just ignore it. Only fail if signing is set to "required". Jeremy. (This used to be commit ab5db8873e2882900baa1c74706bb907baaff7fd) --- source3/libsmb/smb_signing.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index eec991072d..2a53638d17 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -370,7 +370,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); #endif /* JRATEST */ } else { - DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, (const char *)server_sent_mac, 8); } return signing_good(inbuf, si, good, saved_seq); @@ -743,7 +743,24 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); dump_data(10, (const char *)server_sent_mac, 8); } - return signing_good(inbuf, si, good, saved_seq); + + if (!signing_good(inbuf, si, good, saved_seq)) { + if (si->mandatory_signing) { + /* Mandatory signing - fail and disconnect. */ + return False; + } else { + /* Non-mandatory signing - just turn off. */ + DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ +isn't sending correct signatures. Turning off.\n")); + si->negotiated_smb_signing = False; + si->allow_smb_signing = False; + si->doing_signing = False; + free_signing_context(si); + return True; + } + } else { + return True; + } } /*********************************************************** @@ -967,6 +984,10 @@ void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); + DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n", + BOOLSTR(srv_sign_info.negotiated_smb_signing), + BOOLSTR(srv_sign_info.mandatory_signing) )); + /* Initialise the sequence number */ data->send_seq_num = 0; -- cgit From 90d4b84636b08740c4dd4995250ac53ef345f6ce Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Nov 2003 02:04:10 +0000 Subject: Patch for #263 from jpjanosi@us.ibm.com. Jeremy. (This used to be commit 6543bca0cbf6030d2400e30bb7491237d9c818f8) --- source3/rpc_server/srv_dfs_nt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c index ac3ed9c394..f324fd126e 100644 --- a/source3/rpc_server/srv_dfs_nt.c +++ b/source3/rpc_server/srv_dfs_nt.c @@ -369,6 +369,7 @@ WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, { UNISTR2* uni_path = &q_u->uni_path; uint32 level = q_u->level; + int consumedcnt = sizeof(pstring); pstring path; struct junction_map jn; @@ -377,7 +378,7 @@ WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, return WERR_DFS_NO_SUCH_SERVER; /* The following call can change the cwd. */ - if(!get_referred_path(path, &jn, NULL, NULL)) { + if(!get_referred_path(path, &jn, &consumedcnt, NULL) || consumedcnt < strlen(path)) { vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_NO_SUCH_VOL; } -- cgit From c8d0bce19ff7bf31b1f945b189839281a71aa697 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Nov 2003 18:15:49 +0000 Subject: If signing starts successfully, don't just turn it off automatically if it fails later. Only turn it off automatically if it fails at the start. Jeremy. (This used to be commit 2a00d538da61253455db1734b74ef1debaea24ea) --- source3/libsmb/smb_signing.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 2a53638d17..755a1548eb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -745,11 +745,8 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); } if (!signing_good(inbuf, si, good, saved_seq)) { - if (si->mandatory_signing) { - /* Mandatory signing - fail and disconnect. */ - return False; - } else { - /* Non-mandatory signing - just turn off. */ + if (!si->mandatory_signing && (data->send_seq_num < 3)){ + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ isn't sending correct signatures. Turning off.\n")); si->negotiated_smb_signing = False; @@ -757,6 +754,9 @@ isn't sending correct signatures. Turning off.\n")); si->doing_signing = False; free_signing_context(si); return True; + } else { + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + return False; } } else { return True; -- cgit From 82ef4774d233295d29a3c6f86e30d03eddef9c73 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 25 Nov 2003 19:17:20 +0000 Subject: allow users to delete jobs with cups printing backend The changes the name of the job passed off to cups from "Test Page" to "smbprn.00000033 Test Page" so that we can get the smb jobid back from lpq. Working on bug 770. (This used to be commit 3a84daf24f80cf44605841c844a0ba516354420b) --- source3/printing/print_cups.c | 6 +++++- source3/printing/printing.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index 291028b70c..77719ffc52 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -681,6 +681,7 @@ cups_job_submit(int snum, struct printjob *pjob) cups_lang_t *language; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ char *clientname; /* hostname of client for job-originating-host attribute */ + pstring new_jobname; DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); @@ -743,8 +744,11 @@ cups_job_submit(int snum, struct printjob *pjob) "job-originating-host-name", NULL, clientname); + pstr_sprintf(new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX, + (unsigned int)pjob->smbjob, pjob->jobname); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, - pjob->jobname); + new_jobname); /* * Do the request and get back a response... diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ef532473ba..a4949f78e9 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2062,6 +2062,8 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) return True; } + pjob->smbjob = jobid; + ret = (*(current_printif->job_submit))(snum, pjob); if (ret) -- cgit From e88d4705c1a22636d0aa4dcf5c56e0d3f842da16 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Nov 2003 23:25:15 +0000 Subject: Patch from Jim McDonough for bug #802. Retrieve the correct ACL group bits if the file has an ACL. Jeremy. (This used to be commit a51d9e947ef012fabf5a13250df6232d23722f68) --- source3/smbd/dosmode.c | 3 +++ source3/smbd/posix_acls.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index f88964123e..fb72a2eafc 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -183,6 +183,7 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) /******************************************************************* chmod a file - but preserve some bits ********************************************************************/ + int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_STAT *st) { SMB_STRUCT_STAT st1; @@ -197,6 +198,8 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST return(-1); } + get_acl_group_bits(conn, fname, &st->st_mode); + if (S_ISDIR(st->st_mode)) dosmode |= aDIR; else diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index aa1d25c483..8033c694f5 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3177,6 +3177,48 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) return True; } +/**************************************************************************** + Get the actual group bits stored on a file with an ACL. Has no effect if + the file has no ACL. Needed in dosmode code where the stat() will return + the mask bits, not the real group bits, for a file with an ACL. +****************************************************************************/ + +int get_acl_group_bits( connection_struct *conn, char *fname, mode_t *mode ) +{ + int entry_id = SMB_ACL_FIRST_ENTRY; + SMB_ACL_ENTRY_T entry; + SMB_ACL_T posix_acl; + + posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS); + if (posix_acl == (SMB_ACL_T)NULL) + return -1; + + while (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) { + SMB_ACL_TAG_T tagtype; + SMB_ACL_PERMSET_T permset; + + /* get_next... */ + if (entry_id == SMB_ACL_FIRST_ENTRY) + entry_id = SMB_ACL_NEXT_ENTRY; + + if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) ==-1) + return -1; + + if (tagtype == SMB_ACL_GROUP_OBJ) { + if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) { + return -1; + } else { + *mode &= ~(S_IRGRP|S_IWGRP|S_IXGRP); + *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? S_IRGRP : 0); + *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? S_IWGRP : 0); + *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? S_IXGRP : 0); + return 0;; + } + } + } + return -1; +} + /**************************************************************************** Do a chmod by setting the ACL USER_OBJ, GROUP_OBJ and OTHER bits in an ACL and set the mask to rwx. Needed to preserve complex ACLs set by NT. -- cgit From 52c1e60e68f8e906ce7c6a82b1c32f29cd546659 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 26 Nov 2003 00:07:55 +0000 Subject: Merge from 3.0: - NTLM2 fixes, don't force NTLM2 - Don't use NTLM2 for RPC, it doesn't work yet - Add comments to winbindd_pam.c - Merge 64 bit fixes and better debug messages in winbindd.c Andrew Bartlett (This used to be commit ba94e4a1ab6dc3335bbb29686ca6795d0ffad5b0) --- source3/libsmb/ntlmssp.c | 8 ++++++-- source3/nsswitch/winbindd.c | 6 +++--- source3/nsswitch/winbindd_pam.c | 2 ++ source3/rpc_client/cli_pipe.c | 12 ++++-------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index a0da1efcc1..d361196047 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -774,8 +774,6 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; } - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - /* generate the ntlmssp negotiate packet */ msrpc_gen(next_request, "CddAA", "NTLMSSP", @@ -812,6 +810,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB encrypted_session_key = data_blob(NULL, 0); + NTSTATUS nt_status; if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", @@ -1002,6 +1001,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->expected_state = NTLMSSP_UNKNOWN; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { + DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); + return nt_status; + } + return NT_STATUS_MORE_PROCESSING_REQUIRED; } diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 4f161604b5..4b47ac13a2 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -452,7 +452,7 @@ void winbind_client_read(struct winbindd_cli_state *state) (char *)&state->request, sizeof(state->request) - state->read_buf_len); - DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n, sizeof(state->request) - n - state->read_buf_len )); + DEBUG(10,("client_read: read %d bytes. Need %ld more for a full request.\n", n, (unsigned long)(sizeof(state->request) - n - state->read_buf_len) )); /* Read failed, kill client */ @@ -719,8 +719,8 @@ static void process_loop(void) if (state->read_buf_len >= sizeof(uint32) && *(uint32 *) &state->request != sizeof(state->request)) { - DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %d\n", - (unsigned long)state->request.pid, *(uint32 *) &state->request, sizeof(state->request))); + DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %ld\n", + (unsigned long)state->request.pid, *(uint32 *) &state->request, (unsigned long)sizeof(state->request))); remove_client(state); break; diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 993e7d68ff..9962105787 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -383,6 +383,8 @@ done: state->response.data.auth.nt_status = NT_STATUS_V(result); push_utf8_fstring(state->response.data.auth.nt_status_string, nt_errstr(result)); + + /* we might have given a more useful error above */ if (!*state->response.data.auth.error_string) push_utf8_fstring(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); state->response.data.auth.pam_error = nt_status_to_pam(result); diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7517777920..49abf787ee 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -822,14 +822,6 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli, return NT_STATUS_NO_MEMORY; } - if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - nt_status = ntlmssp_sign_init(cli->ntlmssp_pipe_state); - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - } - data_blob_free(&ntlmssp_reply); return NT_STATUS_OK; } @@ -1336,6 +1328,10 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na if (!NT_STATUS_IS_OK(nt_status)) return False; + /* Currently the NTLMSSP code does not implement NTLM2 correctly for signing or sealing */ + + cli->ntlmssp_pipe_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + nt_status = ntlmssp_set_username(cli->ntlmssp_pipe_state, cli->user_name); if (!NT_STATUS_IS_OK(nt_status)) -- cgit From 449b2e42674180e43f2b4079466c0f43f8122035 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 26 Nov 2003 10:01:31 +0000 Subject: Get rid of a const warning Volker (This used to be commit ab1096d58e2447bc91370e0a7f913d9375658c4c) --- source3/libads/ldap.c | 2 +- source3/utils/net_ads.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2ee8e6fe93..775a504f2b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1929,7 +1929,7 @@ bin/net -Uadministrator%XXXXX ads search '(&(objectclass=crossref)(dnsroot=VNET3 but you need to force the bind path to match the configurationNamingContext from the rootDSE */ -ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) +ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **workgroup) { char *expr; ADS_STATUS rc; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index cad93608dc..9404ae4b24 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -209,7 +209,7 @@ static int net_ads_workgroup(int argc, const char **argv) { ADS_STRUCT *ads; TALLOC_CTX *ctx; - char *workgroup; + const char *workgroup; if (!(ads = ads_startup())) return -1; @@ -656,7 +656,7 @@ int net_ads_join(int argc, const char **argv) char *ou_str; uint32 sec_channel_type = SEC_CHAN_WKSTA; uint32 account_type = UF_WORKSTATION_TRUST_ACCOUNT; - char *short_domain_name = NULL; + const char *short_domain_name = NULL; TALLOC_CTX *ctx = NULL; if (argc > 0) org_unit = argv[0]; -- cgit From 63d44a5c2d1dc253c9990ca5f3fbf5eedf7bba8f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 26 Nov 2003 10:09:59 +0000 Subject: Implement "net rpc group members": Get members of a domain group in human-readable format. Volker (This used to be commit e5770a9433099f86a1f828a35bbecbe5691c000c) --- source3/utils/net_help.c | 1 + source3/utils/net_rpc.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index c688beef72..059da4740b 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -93,6 +93,7 @@ int net_help_group(int argc, const char **argv) "\n\tDelete specified group\n"); d_printf("\nnet [] group ADD [-C comment] [-c container]"\ " [misc. options] [targets]\n\tCreate specified group\n"); + d_printf("\nnet rpc group MEMBERS \n\tList Group Members\n\n"); net_common_methods_usage(argc, argv); net_common_flags_usage(argc, argv); d_printf("\t-C or --comment=\tdescriptive comment (for add only)\n"); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 747fc63e23..af575d9585 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1064,6 +1064,93 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, return result; } +static NTSTATUS +rpc_group_members_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + NTSTATUS result; + POLICY_HND connect_pol, domain_pol, group_pol; + uint32 num_rids, *rids, *rid_types; + uint32 num_members, *group_rids, *group_attrs; + uint32 num_names; + char **names; + uint32 *name_types; + int i; + + /* Get sam policy handle */ + + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Get domain policy handle */ + + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + domain_sid, &domain_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, + 1, argv, &num_rids, &rids, &rid_types); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + if (num_rids != 1) { + d_printf("Could not find group %s\n", argv[0]); + goto done; + } + + if (rid_types[0] != SID_NAME_DOM_GRP) { + d_printf("%s is not a domain group\n", argv[0]); + goto done; + } + + result = cli_samr_open_group(cli, mem_ctx, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + rids[0], &group_pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol, + &num_members, &group_rids, + &group_attrs); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol, 1000, + num_members, group_rids, + &num_names, &names, &name_types); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + for (i = 0; i < num_members; i++) { + printf("%s\n", names[i]); + } + + done: + return result; +} + +static int rpc_group_members(int argc, const char **argv) +{ + if (argc != 1) { + return rpc_group_usage(argc, argv); + } + + return run_rpc_command(NULL, PI_SAMR, 0, + rpc_group_members_internals, + argc, argv); +} + /** * 'net rpc group' entrypoint. * @param argc Standard main() style argc @@ -1078,6 +1165,7 @@ int net_rpc_group(int argc, const char **argv) {"add", rpc_group_add}, {"delete", rpc_group_delete}, #endif + {"members", rpc_group_members}, {NULL, NULL} }; -- cgit From b1b4d67f651d50eca369683e18736d40337af96d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Nov 2003 20:58:51 +0000 Subject: Patch from Benjamin Riefenstahl to add MacOSX (Darwin) specific charset module code. Also had to add AC_CHECK_CPP to configure.in (this took a *long* time to track down) to make autoconf work correctly on Fedora Core 1. Jeremy. (This used to be commit a5711943428e4b586fb7f064739c78fa0a3ebd52) --- source3/Makefile.in | 6 + source3/configure.in | 56 +++- source3/modules/charset_macosxfs.c | 602 +++++++++++++++++++++++++++++++++++++ 3 files changed, 651 insertions(+), 13 deletions(-) create mode 100644 source3/modules/charset_macosxfs.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 6141fd500b..dd8aaee6c4 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -302,6 +302,7 @@ MYSQL_OBJ = passdb/pdb_mysql.o DEVEL_HELP_WEIRD_OBJ = modules/weird.o CP850_OBJ = modules/CP850.o CP437_OBJ = modules/CP437.o +CHARSET_MACOSXFS_OBJ = modules/charset_macosxfs.o GROUPDB_OBJ = groupdb/mapping.o @@ -1114,6 +1115,11 @@ bin/CP437.@SHLIBEXT@: $(CP437_OBJ:.o=.@PICSUFFIX@) @$(SHLD) $(LDSHFLAGS) -o $@ $(CP437_OBJ:.o=.@PICSUFFIX@) \ @SONAMEFLAG@`basename $@` +bin/macosxfs.@SHLIBEXT@: $(CHARSET_MACOSXFS_OBJ:.o=.po) + @echo "Building plugin $@" + @$(SHLD) $(LDSHFLAGS) -o $@ $(CHARSET_MACOSXFS_OBJ:.o=.po) \ + -framework CoreFoundation @SONAMEFLAG@`basename $@` + bin/xml.@SHLIBEXT@: $(XML_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(XML_OBJ:.o=.@PICSUFFIX@) @XML_LIBS@ \ diff --git a/source3/configure.in b/source3/configure.in index 64fd7bd168..5c4580f14a 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -126,6 +126,25 @@ AC_ARG_WITH(logfilebase, ;; esac]) +AC_ARG_WITH(cfenc, +[ --with-cfenc=HEADERDIR Use internal CoreFoundation encoding API + for optimization (Mac OS X/Darwin only)], +[ +# May be in source $withval/CoreFoundation/StringEncodings.subproj. +# Should have been in framework $withval/CoreFoundation.framework/Headers. +for d in \ + $withval/CoreFoundation/StringEncodings.subproj \ + $withval/StringEncodings.subproj \ + $withval/CoreFoundation.framework/Headers \ + $withval/Headers \ + $withval +do + if test -r $d/CFStringEncodingConverter.h; then + ln -sfh $d include/CoreFoundation + fi +done +]) + AC_SUBST(configdir) AC_SUBST(lockdir) AC_SUBST(piddir) @@ -203,6 +222,10 @@ OLD_CFLAGS=${CFLAGS} AC_PROG_CC CFLAGS=${OLD_CFLAGS} +OLD_CFLAGS=${CFLAGS} +AC_PROG_CPP +CFLAGS=${OLD_CFLAGS} + AC_PROG_INSTALL AC_PROG_AWK AC_PATH_PROG(PERL, perl) @@ -432,7 +455,7 @@ case "$host_os" in *) CPPFLAGS="$CPPFLAGS -D_SYSV" AC_DEFINE(_SYSV, 1, [Whether to enable System V compatibility]) - esac + esac ;; # # Tests needed for SINIX large file support. @@ -504,15 +527,15 @@ main() { #endif } ], [LINUX_LFS_SUPPORT=yes], [LINUX_LFS_SUPPORT=no], [LINUX_LFS_SUPPORT=cross]) - CPPFLAGS="$old_CPPFLAGS" - if test x$LINUX_LFS_SUPPORT = xyes ; then - CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" - AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support]) - AC_DEFINE(_FILE_OFFSET_BITS, 64, [File offset bits]) - AC_DEFINE(_GNU_SOURCE, 1, [Whether to use GNU libc extensions]) - fi - AC_MSG_RESULT([$LINUX_LFS_SUPPORT]) - ;; + CPPFLAGS="$old_CPPFLAGS" + if test x$LINUX_LFS_SUPPORT = xyes ; then + CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" + AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support]) + AC_DEFINE(_FILE_OFFSET_BITS, 64, [File offset bits]) + AC_DEFINE(_GNU_SOURCE, 1, [Whether to use GNU libc extensions]) + fi + AC_MSG_RESULT([$LINUX_LFS_SUPPORT]) + ;; # # MacOS X is the *only* system that uses compose character in utf8. This @@ -530,10 +553,16 @@ main() { # use that instead of plain dlsym. AC_CHECK_LIB(dl,dlopen) - AC_CHECK_FUNCS(dlsym_prepend_underscore, - [CPPFLAGS="$CPPFLAGS -Ddlsym=dlsym_prepend_underscore"]) + AC_CHECK_FUNCS(dlsym_prepend_underscore,[CPPFLAGS="$CPPFLAGS -Ddlsym=dlsym_prepend_underscore"]) - ;; +#Add a system specific charset module. + + default_shared_modules="$default_shared_modules charset_macosxfs" + old_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="-Iinclude $CPPFLAGS" + AC_CHECK_HEADERS([CoreFoundation/CFStringEncodingConverter.h], [], [AC_CHECK_HEADERS([CFStringEncodingConverter.h])]) + CPPFLAGS="$old_CPPFLAGS" + ;; *hurd*) AC_MSG_CHECKING([for LFS support]) old_CPPFLAGS="$CPPFLAGS" @@ -4178,6 +4207,7 @@ SMB_SUBSYSTEM(IDMAP,sam/idmap.o) SMB_MODULE(charset_weird, modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET) SMB_MODULE(charset_CP850, modules/CP850.o, "bin/CP850.$SHLIBEXT", CHARSET) SMB_MODULE(charset_CP437, modules/CP437.o, "bin/CP437.$SHLIBEXT", CHARSET) +SMB_MODULE(charset_macosxfs, modules/charset_macosxfs.o,"bin/macosxfs.$SHLIBEXT", CHARSET) SMB_SUBSYSTEM(CHARSET,lib/iconv.o) SMB_MODULE(auth_rhosts, \$(AUTH_RHOSTS_OBJ), "bin/rhosts.$SHLIBEXT", AUTH) diff --git a/source3/modules/charset_macosxfs.c b/source3/modules/charset_macosxfs.c new file mode 100644 index 0000000000..6f50d879ba --- /dev/null +++ b/source3/modules/charset_macosxfs.c @@ -0,0 +1,602 @@ +/* + Unix SMB/CIFS implementation. + Samba charset module for Mac OS X/Darwin + Copyright (C) Benjamin Riefenstahl 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * modules/charset_macosxfs.c + * + * A Samba charset module to use on Mac OS X/Darwin as the filesystem + * and display encoding. + * + * Actually two implementations are provided here. The default + * implementation is based on the official CFString API. The other is + * based on internal CFString APIs as defined in the OpenDarwin + * source. + */ + +#include "includes.h" + +/* + * Include OS frameworks. These are only needed in this module. + */ +#include + +/* + * See if autoconf has found us the internal headers in some form. + */ +#if HAVE_COREFOUNDATION_CFSTRINGENCODINGCONVERTER_H +# include +# include +# define USE_INTERNAL_API 1 +#elif HAVE_CFSTRINGENCODINGCONVERTER_H +# include +# include +# define USE_INTERNAL_API 1 +#endif + +/* + * Compile time configuration: Do we want debug output? + */ +/* #define DEBUG_STRINGS 1 */ + +/* + * A simple, but efficient memory provider for our buffers. + */ +static inline void *resize_buffer (void *buffer, size_t *size, size_t newsize) +{ + if (newsize > *size) { + *size = newsize + 128; + buffer = realloc(buffer, *size); + } + return buffer; +} + +/* + * While there is a version of OpenDarwin for intel, the usual case is + * big-endian PPC. So we need byte swapping to handle the + * little-endian byte order of the network protocol. We also need an + * additional dynamic buffer to do this work for incoming data blocks, + * because we have to consider the original data as constant. + * + * We abstract the differences away by providing a simple facade with + * these functions/macros: + * + * le_to_native(dst,src,len) + * native_to_le(cp,len) + * set_ucbuffer_with_le(buffer,bufsize,data,size) + * set_ucbuffer_with_le_copy(buffer,bufsize,data,size,reserve) + */ +#ifdef WORDS_BIGENDIAN + +static inline void swap_bytes (char * dst, const char * src, size_t len) +{ + const char *srcend = src + len; + while (src < srcend) { + dst[0] = src[1]; + dst[1] = src[0]; + dst += 2; + src += 2; + } +} +static inline void swap_bytes_inplace (char * cp, size_t len) +{ + char temp; + char *end = cp + len; + while (cp < end) { + temp = cp[1]; + cp[1] = cp[0]; + cp[0] = temp; + cp += 2; + } +} + +#define le_to_native(dst,src,len) swap_bytes(dst,src,len) +#define native_to_le(cp,len) swap_bytes_inplace(cp,len) +#define set_ucbuffer_with_le(buffer,bufsize,data,size) \ + set_ucbuffer_with_le_copy(buffer,bufsize,data,size,0) + +#else /* ! WORDS_BIGENDIAN */ + +#define le_to_native(dst,src,len) memcpy(dst,src,len) +#define native_to_le(cp,len) /* nothing */ +#define set_ucbuffer_with_le(buffer,bufsize,data,size) \ + (((void)(bufsize)),(UniChar*)(data)) + +#endif + +static inline UniChar *set_ucbuffer_with_le_copy ( + UniChar *buffer, size_t *bufsize, + const void *data, size_t size, size_t reserve) +{ + buffer = resize_buffer(buffer, bufsize, size+reserve); + le_to_native((char*)buffer,data,size); + return buffer; +} + + +/* + * A simple hexdump function for debugging error conditions. + */ +#define debug_out(s) DEBUG(0,(s)) + +#ifdef DEBUG_STRINGS + +static void hexdump( const char * label, const char * s, size_t len ) +{ + size_t restlen = len; + debug_out("<<<<<<<\n"); + debug_out(label); + debug_out("\n"); + while (restlen > 0) { + char line[100]; + size_t i, j; + char * d = line; +#undef sprintf + d += sprintf(d, "%04X ", (unsigned)(len-restlen)); + *d++ = ' '; + for( i = 0; i= 0x7F || !isprint(s[i])) + *d++ = '.'; + else + *d++ = s[i]; + } + *d++ = '\n'; + *d = 0; + restlen -= i; + s += i; + debug_out(line); + } + debug_out(">>>>>>>\n"); +} + +#else /* !DEBUG_STRINGS */ + +#define hexdump(label,s,len) /* nothing */ + +#endif + + +#if !USE_INTERNAL_API + +/* + * An implementation based on documented Mac OS X APIs. + * + * This does a certain amount of memory management, creating and + * manipulating CFString objects. We try to minimize the impact by + * keeping those objects around and re-using them. We also use + * external backing store for the CFStrings where this is possible and + * benficial. + * + * The Unicode normalizations forms available at this level are + * generic, not specifically for the file system. So they may not be + * perfect fits. + */ +static size_t macosxfs_encoding_pull( + void *cd, /* Encoder handle */ + char **inbuf, size_t *inbytesleft, /* Script string */ + char **outbuf, size_t *outbytesleft) /* UTF-16-LE string */ +{ + static const int script_code = kCFStringEncodingUTF8; + static CFMutableStringRef cfstring = NULL; + size_t outsize; + CFRange range; + + (void) cd; /* UNUSED */ + + if (0 == *inbytesleft) { + return 0; + } + + if (NULL == cfstring) { + /* + * A version with an external backing store as in the + * push function should have been more efficient, but + * testing shows, that it is actually slower (!). + * Maybe kCFAllocatorDefault gets shortcut evaluation + * internally, while kCFAllocatorNull doesn't. + */ + cfstring = CFStringCreateMutable(kCFAllocatorDefault,0); + } + + /* + * Three methods of appending to a CFString, choose the most + * efficient. + */ + if (0 == (*inbuf)[*inbytesleft-1]) { + CFStringAppendCString(cfstring, *inbuf, script_code); + } else if (*inbytesleft <= 255) { + Str255 buffer; + buffer[0] = *inbytesleft; + memcpy(buffer+1, *inbuf, buffer[0]); + CFStringAppendPascalString(cfstring, buffer, script_code); + } else { + /* + * We would like to use a fixed buffer and a loop + * here, but than we can't garantee that the input is + * well-formed UTF-8, as we are supposed to do. + */ + static char *buffer = NULL; + static size_t buflen = 0; + buffer = resize_buffer(buffer, &buflen, *inbytesleft+1); + memcpy(buffer, *inbuf, *inbytesleft); + buffer[*inbytesleft] = 0; + CFStringAppendCString(cfstring, *inbuf, script_code); + } + + /* + * Compose characters, using the non-canonical composition + * form. + */ + CFStringNormalize(cfstring, kCFStringNormalizationFormC); + + outsize = CFStringGetLength(cfstring); + range = CFRangeMake(0,outsize); + + if (outsize == 0) { + /* + * HACK: smbd/mangle_hash2.c:is_legal_name() expects + * errors here. That function will always pass 2 + * characters. smbd/open.c:check_for_pipe() cuts a + * patchname to 10 characters blindly. Suppress the + * debug output in those cases. + */ + if(2 != *inbytesleft && 10 != *inbytesleft) { + debug_out("String conversion: " + "An unknown error occurred\n"); + hexdump("UTF8->UTF16LE (old) input", + *inbuf, *inbytesleft); + } + errno = EILSEQ; /* Not sure, but this is what we have + * actually seen. */ + return -1; + } + if (outsize*2 > *outbytesleft) { + CFStringDelete(cfstring, range); + debug_out("String conversion: " + "Output buffer too small\n"); + hexdump("UTF8->UTF16LE (old) input", + *inbuf, *inbytesleft); + errno = E2BIG; + return -1; + } + + CFStringGetCharacters(cfstring, range, (UniChar*)*outbuf); + CFStringDelete(cfstring, range); + + native_to_le(*outbuf, outsize*2); + + /* + * Add a converted null byte, if the CFString conversions + * prevented that until now. + */ + if (0 == (*inbuf)[*inbytesleft-1] && + (0 != (*outbuf)[outsize*2-1] || 0 != (*outbuf)[outsize*2-2])) { + + if ((outsize*2+2) > *outbytesleft) { + debug_out("String conversion: " + "Output buffer too small\n"); + hexdump("UTF8->UTF16LE (old) input", + *inbuf, *inbytesleft); + errno = E2BIG; + return -1; + } + + (*outbuf)[outsize*2] = (*outbuf)[outsize*2+1] = 0; + outsize += 2; + } + + *inbuf += *inbytesleft; + *inbytesleft = 0; + *outbuf += outsize*2; + *outbytesleft -= outsize*2; + + return 0; +} + +static size_t macosxfs_encoding_push( + void *cd, /* Encoder handle */ + char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */ + char **outbuf, size_t *outbytesleft) /* Script string */ +{ + static const int script_code = kCFStringEncodingUTF8; + static CFMutableStringRef cfstring = NULL; + static UniChar *buffer = NULL; + static size_t buflen = 0; + CFIndex outsize, cfsize, charsconverted; + + (void) cd; /* UNUSED */ + + if (0 == *inbytesleft) { + return 0; + } + + /* + * We need a buffer that can hold 4 times the original data, + * because that is the theoretical maximum that decomposition + * can create currently (in Unicode 4.0). + */ + buffer = set_ucbuffer_with_le_copy( + buffer, &buflen, *inbuf, *inbytesleft, 3 * *inbytesleft); + + if (NULL == cfstring) { + cfstring = CFStringCreateMutableWithExternalCharactersNoCopy( + kCFAllocatorDefault, + buffer, *inbytesleft/2, buflen/2, + kCFAllocatorNull); + } else { + CFStringSetExternalCharactersNoCopy( + cfstring, + buffer, *inbytesleft/2, buflen/2); + } + + /* + * Decompose characters, using the non-canonical decomposition + * form. + * + * NB: This isn't exactly what HFS+ wants (see note on + * kCFStringEncodingUseHFSPlusCanonical in + * CFStringEncodingConverter.h), but AFAIK it's the best that + * the official API can do. + */ + CFStringNormalize(cfstring, kCFStringNormalizationFormD); + + cfsize = CFStringGetLength(cfstring); + charsconverted = CFStringGetBytes( + cfstring, CFRangeMake(0,cfsize), + script_code, 0, False, + *outbuf, *outbytesleft, &outsize); + + if (0 == charsconverted) { + debug_out("String conversion: " + "Buffer too small or not convertable\n"); + hexdump("UTF16LE->UTF8 (old) input", + *inbuf, *inbytesleft); + errno = EILSEQ; /* Probably more likely. */ + return -1; + } + + /* + * Add a converted null byte, if the CFString conversions + * prevented that until now. + */ + if (0 == (*inbuf)[*inbytesleft-1] && 0 == (*inbuf)[*inbytesleft-2] && + (0 != (*outbuf)[outsize-1])) { + + if (((size_t)outsize+1) > *outbytesleft) { + debug_out("String conversion: " + "Output buffer too small\n"); + hexdump("UTF16LE->UTF8 (old) input", + *inbuf, *inbytesleft); + errno = E2BIG; + return -1; + } + + (*outbuf)[outsize] = 0; + ++outsize; + } + + *inbuf += *inbytesleft; + *inbytesleft = 0; + *outbuf += outsize; + *outbytesleft -= outsize; + + return 0; +} + +#else /* USE_INTERNAL_API */ + +/* + * An implementation based on internal code as known from the + * OpenDarwin CVS. + * + * This code doesn't need much memory management because it uses + * functions that operate on the raw memory directly. + * + * The push routine here is faster and more compatible with HFS+ than + * the other implementation above. The pull routine is only faster + * for some strings, slightly slower for others. The pull routine + * looses because it has to iterate over the data twice, once to + * decode UTF-8 and than to do the character composition required by + * Windows. + */ +static size_t macosxfs_encoding_pull( + void *cd, /* Encoder handle */ + char **inbuf, size_t *inbytesleft, /* Script string */ + char **outbuf, size_t *outbytesleft) /* UTF-16-LE string */ +{ + static const int script_code = kCFStringEncodingUTF8; + UInt32 srcCharsUsed = 0; + UInt32 dstCharsUsed = 0; + UInt32 result; + uint32_t dstDecomposedUsed = 0; + uint32_t dstPrecomposedUsed = 0; + + (void) cd; /* UNUSED */ + + if (0 == *inbytesleft) { + return 0; + } + + result = CFStringEncodingBytesToUnicode( + script_code, kCFStringEncodingComposeCombinings, + *inbuf, *inbytesleft, &srcCharsUsed, + (UniChar*)*outbuf, *outbytesleft, &dstCharsUsed); + + switch(result) { + case kCFStringEncodingConversionSuccess: + if (*inbytesleft == srcCharsUsed) + break; + else + ; /*fall through*/ + case kCFStringEncodingInsufficientOutputBufferLength: + debug_out("String conversion: " + "Output buffer too small\n"); + hexdump("UTF8->UTF16LE (new) input", + *inbuf, *inbytesleft); + errno = E2BIG; + return -1; + case kCFStringEncodingInvalidInputStream: + /* + * HACK: smbd/mangle_hash2.c:is_legal_name() expects + * errors here. That function will always pass 2 + * characters. smbd/open.c:check_for_pipe() cuts a + * patchname to 10 characters blindly. Suppress the + * debug output in those cases. + */ + if(2 != *inbytesleft && 10 != *inbytesleft) { + debug_out("String conversion: " + "Invalid input sequence\n"); + hexdump("UTF8->UTF16LE (new) input", + *inbuf, *inbytesleft); + } + errno = EILSEQ; + return -1; + case kCFStringEncodingConverterUnavailable: + debug_out("String conversion: " + "Unknown encoding\n"); + hexdump("UTF8->UTF16LE (new) input", + *inbuf, *inbytesleft); + errno = EINVAL; + return -1; + } + + /* + * It doesn't look like CFStringEncodingBytesToUnicode() can + * produce precomposed characters (flags=ComposeCombinings + * doesn't do it), so we need another pass over the data here. + * We can do this in-place, as the string can only get + * shorter. + * + * (Actually in theory there should be an internal + * decomposition and reordering before the actual composition + * step. But we should be able to rely on that we always get + * fully decomposed strings for input, so this can't create + * problems in reality.) + */ + CFUniCharPrecompose( + (const UTF16Char *)*outbuf, dstCharsUsed, &dstDecomposedUsed, + (UTF16Char *)*outbuf, dstCharsUsed, &dstPrecomposedUsed); + + native_to_le(*outbuf, dstPrecomposedUsed*2); + + *inbuf += srcCharsUsed; + *inbytesleft -= srcCharsUsed; + *outbuf += dstPrecomposedUsed*2; + *outbytesleft -= dstPrecomposedUsed*2; + + return 0; +} + +static size_t macosxfs_encoding_push( + void *cd, /* Encoder handle */ + char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */ + char **outbuf, size_t *outbytesleft) /* Script string */ +{ + static const int script_code = kCFStringEncodingUTF8; + static UniChar *buffer = NULL; + static size_t buflen = 0; + UInt32 srcCharsUsed=0, dstCharsUsed=0, result; + + (void) cd; /* UNUSED */ + + if (0 == *inbytesleft) { + return 0; + } + + buffer = set_ucbuffer_with_le( + buffer, &buflen, *inbuf, *inbytesleft); + + result = CFStringEncodingUnicodeToBytes( + script_code, kCFStringEncodingUseHFSPlusCanonical, + buffer, *inbytesleft/2, &srcCharsUsed, + *outbuf, *outbytesleft, &dstCharsUsed); + + switch(result) { + case kCFStringEncodingConversionSuccess: + if (*inbytesleft/2 == srcCharsUsed) + break; + else + ; /*fall through*/ + case kCFStringEncodingInsufficientOutputBufferLength: + debug_out("String conversion: " + "Output buffer too small\n"); + hexdump("UTF16LE->UTF8 (new) input", + *inbuf, *inbytesleft); + errno = E2BIG; + return -1; + case kCFStringEncodingInvalidInputStream: + /* + * HACK: smbd/open.c:check_for_pipe():is_legal_name() + * cuts a pathname to 10 characters blindly. Suppress + * the debug output in those cases. + */ + if(10 != *inbytesleft) { + debug_out("String conversion: " + "Invalid input sequence\n"); + hexdump("UTF16LE->UTF8 (new) input", + *inbuf, *inbytesleft); + } + errno = EILSEQ; + return -1; + case kCFStringEncodingConverterUnavailable: + debug_out("String conversion: " + "Unknown encoding\n"); + hexdump("UTF16LE->UTF8 (new) input", + *inbuf, *inbytesleft); + errno = EINVAL; + return -1; + } + + *inbuf += srcCharsUsed*2; + *inbytesleft -= srcCharsUsed*2; + *outbuf += dstCharsUsed; + *outbytesleft -= dstCharsUsed; + + return 0; +} + +#endif /* USE_INTERNAL_API */ + +/* + * For initialization, actually install the encoding as "macosxfs". + */ +static struct charset_functions macosxfs_encoding_functions = { + "MACOSXFS", macosxfs_encoding_pull, macosxfs_encoding_push +}; + +NTSTATUS init_module(void) +{ + return smb_register_charset(&macosxfs_encoding_functions); +} + +/* eof */ -- cgit