diff options
-rw-r--r-- | source/auth/auth.c | 85 | ||||
-rw-r--r-- | source/auth/auth_builtin.c | 31 | ||||
-rw-r--r-- | source/auth/auth_info.c | 37 | ||||
-rw-r--r-- | source/auth/auth_unix.c | 22 | ||||
-rw-r--r-- | source/param/loadparm.c | 2 | ||||
-rw-r--r-- | source/utils/net_rpc.c | 274 | ||||
-rw-r--r-- | source/utils/net_rpc_join.c | 12 |
7 files changed, 356 insertions, 107 deletions
diff --git a/source/auth/auth.c b/source/auth/auth.c index 710b5f27fbf..94927fe96e3 100644 --- a/source/auth/auth.c +++ b/source/auth/auth.c @@ -23,11 +23,18 @@ #include "includes.h" -/**************************************************************************** - Check user is in correct domain if required -****************************************************************************/ - -static BOOL check_domain_match(char *user, char *domain) +/** + * Check user is in correct domain (if required) + * + * @param user Only used to fill in the debug message + * + * @param domain The domain to be verified + * + * @return True if the user can connect with that domain, + * False otherwise. +**/ + +static BOOL check_domain_match(const char *user, const char *domain) { /* * If we aren't serving to trusted domains, we must make sure that @@ -46,22 +53,37 @@ static BOOL check_domain_match(char *user, char *domain) } } -/**************************************************************************** - Check a users password, as given in the user-info struct and return various - interesting details in the server_info struct. - - This functions does NOT need to be in a become_root()/unbecome_root() pair - as it makes the calls itself when needed. - - The return value takes precedence over the contents of the server_info - struct. When the return is other than NT_STATUS_NOPROBLEMO the contents - of that structure is undefined. - -****************************************************************************/ +/** + * Check a user's Plaintext, LM or NTLM password. + * + * Check a user's password, as given in the user_info struct and return various + * interesting details in the server_info struct. + * + * This function does NOT need to be in a become_root()/unbecome_root() pair + * as it makes the calls itself when needed. + * + * The return value takes precedence over the contents of the server_info + * struct. When the return is other than NT_STATUS_OK the contents + * of that structure is undefined. + * + * @param user_info Contains the user supplied components, including the passwords. + * Must be created with make_user_info() or one of its wrappers. + * + * @param auth_info Supplies the challanges and some other data. + * Must be created with make_auth_info(), and the challanges should be + * filled in, either at creation or by calling the challange geneation + * function auth_get_challange(). + * + * @param server_info If successful, contains information about the authenticaion, + * including a SAM_ACCOUNT struct describing the user. + * + * @return An NTSTATUS with NT_STATUS_OK or an appropriate error. + * + **/ NTSTATUS check_password(const auth_usersupplied_info *user_info, - const auth_authsupplied_info *auth_info, - auth_serversupplied_info **server_info) + const auth_authsupplied_info *auth_info, + auth_serversupplied_info **server_info) { NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; @@ -92,6 +114,11 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info, dump_data(100, user_info->nt_resp.data, user_info->nt_resp.length); #endif + /* This needs to be sorted: If it doesn't match, what should we do? */ + if (!check_domain_match(user_info->smb_name.str, user_info->domain.str)) { + return NT_STATUS_LOGON_FAILURE; + } + for (auth_method = auth_info->auth_method_list;auth_method; auth_method = auth_method->next) { nt_status = auth_method->auth(auth_method->private_data, user_info, auth_info, server_info); @@ -108,12 +135,6 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info, } } - /* This needs to be sorted: If it doesn't match, what should we do? */ - if (!check_domain_match(user_info->smb_name.str, user_info->domain.str)) { - return NT_STATUS_LOGON_FAILURE; - } - - /* This is one of the few places the *relies* (rather than just sets defaults on the value of lp_security(). This needs to change. A new paramater perhaps? */ @@ -158,10 +179,16 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info, } -/**************************************************************************** - Squash an NT_STATUS return in line with requirements for unauthenticated - connections. (session setups in particular) -****************************************************************************/ +/** + * Squash an NT_STATUS in line with security requirements. + * In an attempt to avoid giving the whole game away when users + * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and + * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations + * (session setups in particular). + * + * @param nt_status NTSTATUS input for squashing. + * @return the 'squashed' nt_status + **/ NTSTATUS nt_status_squash(NTSTATUS nt_status) { diff --git a/source/auth/auth_builtin.c b/source/auth/auth_builtin.c index 2bba36f754d..8f283fd8564 100644 --- a/source/auth/auth_builtin.c +++ b/source/auth/auth_builtin.c @@ -21,10 +21,13 @@ #include "includes.h" -/**************************************************************************** - Check for a guest logon (username = "") and if so create the required - structure. -****************************************************************************/ +/** + * Return a guest logon for guest users (username = "") + * + * Typically used as the first module in the auth chain, this allows + * guest logons to be delt with in one place. Non-gust logons 'fail' + * and pass onto the next module. + **/ static NTSTATUS check_guest_security(void *my_private_data, const auth_usersupplied_info *user_info, @@ -45,6 +48,7 @@ static NTSTATUS check_guest_security(void *my_private_data, return nt_status; } +/* Guest modules initialisation */ BOOL auth_init_guest(auth_methods **auth_method) { if (!make_auth_methods(auth_method)) { @@ -55,9 +59,18 @@ BOOL auth_init_guest(auth_methods **auth_method) return True; } -/**************************************************************************** - Return an error based on username -****************************************************************************/ +/** + * Return an error based on username + * + * This function allows the testing of obsure errors, as well as the generation + * of NT_STATUS -> DOS error mapping tables. + * + * This module is of no value to end-users. + * + * The password is ignored. + * + * @return An NTSTATUS value based on the username + **/ static NTSTATUS check_name_to_ntstatus_security(void *my_private_data, const auth_usersupplied_info *user_info, @@ -78,6 +91,7 @@ static NTSTATUS check_name_to_ntstatus_security(void *my_private_data, return nt_status; } +/** Module initailisation function */ BOOL auth_init_name_to_ntstatus(auth_methods **auth_method) { if (!make_auth_methods(auth_method)) { @@ -88,3 +102,6 @@ BOOL auth_init_name_to_ntstatus(auth_methods **auth_method) return True; } + + + diff --git a/source/auth/auth_info.c b/source/auth/auth_info.c index cc13d5a8b95..bdd490d3ef8 100644 --- a/source/auth/auth_info.c +++ b/source/auth/auth_info.c @@ -21,6 +21,8 @@ #include "includes.h" +/** List of various built-in authenticaion modules */ + const struct auth_init_function builtin_auth_init_functions[] = { { "guest", auth_init_guest }, { "rhosts", auth_init_rhosts }, @@ -38,6 +40,25 @@ const struct auth_init_function builtin_auth_init_functions[] = { }; /*************************************************************************** + Free a linked list of auth methods +***************************************************************************/ + +static void free_auth_methods_list(auth_methods **list) +{ + if (list != NULL) { + while (*list) { + auth_methods *old_head = *list; + if ((*list)->free_private_data) { + (*list)->free_private_data(&((*list)->private_data)); + } + DLIST_REMOVE(*list, *list); + SAFE_FREE(old_head); + } + + } +} + +/*************************************************************************** Make a auth_info struct ***************************************************************************/ @@ -104,7 +125,10 @@ static BOOL make_auth_info_text_list(auth_authsupplied_info **auth_info, char ** } } - make_auth_info_list(auth_info, list); + if (!make_auth_info_list(auth_info, list)) { + free_auth_methods_list(&list); + return False; + } return True; } @@ -210,17 +234,8 @@ BOOL make_auth_info_fixed(auth_authsupplied_info **auth_info, uchar chal[8]) void free_auth_info(auth_authsupplied_info **auth_info) { - auth_methods *list; if (*auth_info != NULL) { - list = (*auth_info)->auth_method_list; - while (list) { - auth_methods *old_head = list; - if (list->free_private_data) { - list->free_private_data(&(list->private_data)); - } - DLIST_REMOVE(list, list); - SAFE_FREE(old_head); - } + free_auth_methods_list(&(*auth_info)->auth_method_list); data_blob_free(&(*auth_info)->challenge); ZERO_STRUCT(**auth_info); diff --git a/source/auth/auth_unix.c b/source/auth/auth_unix.c index d134ce6909c..2e753cb29ca 100644 --- a/source/auth/auth_unix.c +++ b/source/auth/auth_unix.c @@ -21,11 +21,11 @@ #include "includes.h" -/**************************************************************************** -update the encrypted smbpasswd file from the plaintext username and password - -this ugly hack needs to die, but not quite yet... -*****************************************************************************/ +/** + * update the encrypted smbpasswd file from the plaintext username and password + * + * this ugly hack needs to die, but not quite yet, I think people still use it... + **/ static BOOL update_smbpassword_file(char *user, char *password) { SAM_ACCOUNT *sampass = NULL; @@ -77,10 +77,11 @@ static BOOL update_smbpassword_file(char *user, char *password) } -/**************************************************************************** -check if a username/password is OK assuming the password -in PLAIN TEXT -****************************************************************************/ +/** Check a plaintext username/password + * + * Cannot deal with an encrupted password in any manner whatsoever, + * unless the account has a null password. + **/ NTSTATUS check_unix_security(void *my_private_data, const auth_usersupplied_info *user_info, @@ -93,6 +94,9 @@ NTSTATUS check_unix_security(void *my_private_data, become_root(); pass = Get_Pwnam(user_info->internal_username.str); + + /** This call assumes a ASCII password, no charset transformation is + done. We may need to revisit this **/ nt_status = pass_check(pass, pass ? pass->pw_name : user_info->internal_username.str, (char *)user_info->plaintext_password.data, diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 335995b0dd2..d1448df8d30 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -3862,7 +3862,7 @@ void get_private_directory(pstring privdir) Is netbios alias or name *****************************************************************/ -BOOL is_netbios_alias_or_name(char *name) +BOOL is_netbios_alias_or_name(const char *name) { char **netbios_aliases = lp_netbios_aliases(); diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c index 97a1a1d342b..b98cae37b66 100644 --- a/source/utils/net_rpc.c +++ b/source/utils/net_rpc.c @@ -21,9 +21,32 @@ #include "includes.h" #include "../utils/net.h" - +/** + * @file net_rpc.c + * + * @brief RPC based subcommands for the 'net' utility. + * + * This file should contain much of the functionality that used to + * be found in rpcclient, execpt that the commands should change + * less often, and the fucntionality should be sane (the user is not + * expected to know a rid/sid before they conduct an operation etc.) + * + * @todo Perhaps eventually these should be split out into a number + * of files, as this could get quite big. + **/ + + +/* A function of this type is passed to the 'run_rpc_command' wrapper */ typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_CTX *, int, const char **); +/** + * Many of the RPC functions need the domain sid. This function gets + * it at the start of every run + * + * @param cli A cli_state already connected to the remote machine + * + * @return The Domain SID of the remote machine. + */ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli) { @@ -80,6 +103,17 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli) exit(1); } +/** + * Run a single RPC command, from start to finish. + * + * @param pipe_name the pipe to connect to (usually a PIPE_ constant) + * @param conn_flag a NET_FLAG_ combination. Passed to + * net_make_ipc_connection. + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + * @return A shell status integer (0 for success) + */ static int run_rpc_command(const char *pipe_name, int conn_flags, rpc_command_fn fn, @@ -88,7 +122,14 @@ static int run_rpc_command(const char *pipe_name, int conn_flags, struct cli_state *cli = net_make_ipc_connection(conn_flags); TALLOC_CTX *mem_ctx; NTSTATUS nt_status; - DOM_SID *domain_sid = net_get_remote_domain_sid(cli); + DOM_SID *domain_sid; + + if (!cli) { + return -1; + } + + domain_sid = net_get_remote_domain_sid(cli); + /* Create mem_ctx */ if (!(mem_ctx = talloc_init())) { @@ -113,54 +154,25 @@ static int run_rpc_command(const char *pipe_name, int conn_flags, return (!NT_STATUS_IS_OK(nt_status)); } -static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, - int argc, const char **argv) { - - POLICY_HND connect_pol, domain_pol, user_pol; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - const char *acct_name; - uint16 acb_info; - uint32 unknown, user_rid; - - if (argc != 1) { - d_printf("Usage: net rpc user add username\n"); - return NT_STATUS_OK; - } - - acct_name = argv[0]; - - /* 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; - } - - /* Create domain user */ - acb_info = ACB_NORMAL; - unknown = 0xe005000b; /* No idea what this is - a permission mask? */ +/****************************************************************************/ - result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol, - acct_name, acb_info, unknown, - &user_pol, &user_rid); - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - done: - return result; -} +/** + * Force a change of the trust acccount password. + * + * All paramaters are provided by the run_rpc_command funcion, except for + * argc, argv which are passes 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 argc Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { @@ -168,12 +180,46 @@ static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cl return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup); } +/** + * Force a change of the trust acccount password. + * + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ + static int rpc_changetrustpw(int argc, const char **argv) { return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals, argc, argv); } + +/****************************************************************************/ + + +/** + * Join a domain, the old way. + * + * This uses 'machinename' as the inital password, and changes it. + * + * The password should be created with 'server manager' or eqiv first. + * + * All paramaters are provided by the run_rpc_command funcion, except for + * argc, argv which are passes 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 argc Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ + static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { @@ -188,12 +234,29 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash); } +/** + * Join a domain, the old way. + * + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ + static int rpc_join_oldstyle(int argc, const char **argv) { return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals, argc, argv); } +/** + * Basic usage function for 'net rpc join' + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + **/ + static int rpc_join_usage(int argc, const char **argv) { d_printf(" net rpc join \t to join a domain with admin username & password\n"); @@ -201,6 +264,16 @@ static int rpc_join_usage(int argc, const char **argv) return -1; } +/** + * 'net rpc join' entrypoint. + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + * + * Main 'net_rpc_join()' (where the admain username/password is used) is + * in net_rpc_join.c + **/ + static int rpc_join(int argc, const char **argv) { struct functable func[] = { @@ -215,18 +288,111 @@ static int rpc_join(int argc, const char **argv) return net_run_function(argc, argv, func, rpc_join_usage); } + +/****************************************************************************/ + + +/** + * Add a new user to a remote RPC server + * + * All paramaters are provided by the run_rpc_command funcion, except for + * argc, argv which are passes 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 argc Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ + +static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) { + + POLICY_HND connect_pol, domain_pol, user_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + const char *acct_name; + uint16 acb_info; + uint32 unknown, user_rid; + + if (argc != 1) { + d_printf("Usage: net rpc user add username\n"); + return NT_STATUS_OK; + } + + acct_name = argv[0]; + + /* 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; + } + + /* Create domain user */ + + acb_info = ACB_NORMAL; + unknown = 0xe005000b; /* No idea what this is - a permission mask? */ + + result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol, + acct_name, acb_info, unknown, + &user_pol, &user_rid); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + done: + return result; +} + +/** + * Add a new user to a remote RPC server + * + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ + static int rpc_user_add(int argc, const char **argv) { return run_rpc_command(PIPE_SAMR, 0, rpc_user_add_internals, argc, argv); } +/** + * Basic usage function for 'net rpc join' + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + **/ + static int rpc_user_usage(int argc, const char **argv) { d_printf(" net rpc user add \t to add a user\n"); return -1; } +/** + * 'net rpc user' entrypoint. + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + **/ + static int rpc_user(int argc, const char **argv) { struct functable func[] = { @@ -241,6 +407,13 @@ static int rpc_user(int argc, const char **argv) return net_run_function(argc, argv, func, rpc_user_usage); } +/** + * Basic usage function for 'net rpc join' + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + **/ + int net_rpc_usage(int argc, const char **argv) { d_printf(" net rpc join \tto join a domain \n"); @@ -249,6 +422,13 @@ int net_rpc_usage(int argc, const char **argv) return -1; } +/** + * 'net rpc user' entrypoint. + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + **/ + int net_rpc(int argc, const char **argv) { struct functable func[] = { diff --git a/source/utils/net_rpc_join.c b/source/utils/net_rpc_join.c index 16b0ccbaa80..5f5117c9bc5 100644 --- a/source/utils/net_rpc_join.c +++ b/source/utils/net_rpc_join.c @@ -36,9 +36,15 @@ goto done; \ } -/********************************************************* -Join a domain using the administrator username and password -**********************************************************/ +/** + * Join a domain using the administrator username and password + * + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped. Currently not used. + * @return A shell status integer (0 for success) + * + **/ int net_rpc_join(int argc, const char **argv) { |