Add a pile of doxygen style comments to various parts of Samba. Many of these
authorAndrew Bartlett <abartlet@samba.org>
Sun, 30 Dec 2001 10:54:58 +0000 (10:54 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 30 Dec 2001 10:54:58 +0000 (10:54 +0000)
probably will never actually be genearted, but I like the style in any case.

Also fix a segfault in 'net rpc' when the login failed and a small memory leak
on failure in the auth_info.c code.

Andrew Bartlett

source/auth/auth.c
source/auth/auth_builtin.c
source/auth/auth_info.c
source/auth/auth_unix.c
source/param/loadparm.c
source/utils/net_rpc.c
source/utils/net_rpc_join.c

index 710b5f27fbf796be3567387ca6238d2922e5a852..94927fe96e382793a122b6dc749fe12b1a7f2618 100644 (file)
 
 #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) 
 {
index 2bba36f754d9f81b656e424bbb8e6cc2b19811e7..8f283fd8564a4fcb892ccbf6a2c077b1d56bd094 100644 (file)
 
 #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;
 }
 
+
+
+
index cc13d5a8b95b9e12de4fc0a43bc73d4363bc5dc8..bdd490d3ef848b22a642827f17cf2c814b5ce85c 100644 (file)
@@ -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 },
@@ -37,6 +39,25 @@ const struct auth_init_function builtin_auth_init_functions[] = {
        { NULL, NULL}
 };
 
+/***************************************************************************
+ 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);
index d134ce6909cd45c6eccbbe24a4523563ae72d7f2..2e753cb29ca8b82c8ac0ef7a19f415902911c31f 100644 (file)
 
 #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,
index 335995b0dd2dcb8748464328bc79948e33b95cb4..d1448df8d308bc46fc3d700bd26bea9b0fe69b78 100644 (file)
@@ -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();
        
index 97a1a1d342b6f408d7b24008c7c8ff8cd3033342..b98cae37b661a60cf13db572fdd041630074a79a 100644 (file)
 #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[] = {
index 16b0ccbaa806bb4a81b35600270801659e40b56c..5f5117c9bc585e0eff25fa58a83df49d1303729c 100644 (file)
                 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) 
 {