parsing code for transferring unix and nt security credentials over-the-wire.
authorLuke Leighton <lkcl@samba.org>
Wed, 8 Dec 1999 21:45:57 +0000 (21:45 +0000)
committerLuke Leighton <lkcl@samba.org>
Wed, 8 Dec 1999 21:45:57 +0000 (21:45 +0000)
at present, a unix password is missing from the unix credentials, but is
not _actually_ expected to be needed.  weeelll... maybe :-)

this is used to transfer credentials between smbd and msrpc daemons, down
a unix socket, so that the unix and nt credentials can be inherited by
an msrpc daemon called up from smbd.
(This used to be commit 5e68403bbb6f18e754679d967fee9e259d24211c)

source3/include/rpc_creds.h [new file with mode: 0644]
source3/rpc_parse/parse_creds.c [new file with mode: 0644]

diff --git a/source3/include/rpc_creds.h b/source3/include/rpc_creds.h
new file mode 100644 (file)
index 0000000..54293a6
--- /dev/null
@@ -0,0 +1,88 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   SMB parameters and setup
+   Copyright (C) Andrew Tridgell 1992-1999
+   Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+   
+   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.
+*/
+
+#ifndef _RPC_CREDS_H /* _RPC_CREDS_H */
+#define _RPC_CREDS_H 
+
+typedef struct ntuser_creds
+{
+       fstring user_name;
+       fstring domain;
+       struct pwd_info pwd;
+
+       uint32 ntlmssp_flags;
+
+} CREDS_NT;
+
+typedef struct unixuser_creds
+{
+       fstring user_name;
+
+} CREDS_UNIX;
+
+typedef struct unixsec_creds
+{
+       uint32 uid;
+       uint32 gid;
+       int num_grps;
+       uint32 *grps;
+
+} CREDS_UNIX_SEC;
+
+typedef struct ntsec_creds
+{
+       DOM_SID      sid;
+       SEC_DESC_BUF sd ;
+
+} CREDS_NT_SEC;
+
+typedef struct user_creds
+{
+       BOOL reuse;
+       uint32 ptr_ntc;
+       uint32 ptr_uxc;
+       uint32 ptr_nts;
+       uint32 ptr_uxs;
+
+       CREDS_NT   ntc;
+       CREDS_UNIX uxc;
+
+       CREDS_NT_SEC   nts;
+       CREDS_UNIX_SEC uxs;
+
+
+} CREDS_HYBRID;
+
+typedef struct cred_command
+{
+       uint16 version;
+       uint16 command;
+
+       fstring name;
+
+       uint32 ptr_creds;
+       CREDS_HYBRID *cred;
+
+} CREDS_CMD;
+       
+#endif /* _RPC_CREDS_H */
+
diff --git a/source3/rpc_parse/parse_creds.c b/source3/rpc_parse/parse_creds.c
new file mode 100644 (file)
index 0000000..127557d
--- /dev/null
@@ -0,0 +1,494 @@
+/* 
+ *  Unix SMB/Netbios implementation.
+ *  Version 1.9.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Andrew Tgrpsgell              1992-1999,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ *  Copyright (C) Paul Ashton                  1997-1999.
+ *  
+ *  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, Cambgrpsge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+makes a CREDS_UNIX structure.
+********************************************************************/
+BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name)
+{
+       if (r_u == NULL) return False;
+
+       DEBUG(5,("make_creds_unix\n"));
+
+       fstrcpy(r_u->user_name, user_name);
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL creds_io_unix(char *desc, CREDS_UNIX *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL) return False;
+
+       prs_debug(ps, depth, desc, "creds_io_unix");
+       depth++;
+
+       prs_align(ps);
+       prs_string("user_name", ps, depth,   r_u->user_name, strlen(r_u->user_name), sizeof(r_u->user_name));
+       prs_align(ps);
+
+       return True;
+}
+
+
+/*******************************************************************
+frees a structure.
+********************************************************************/
+void creds_free_unix(CREDS_UNIX *r_u)
+{
+}
+
+/*******************************************************************
+makes a CREDS_UNIX_SEC structure.
+********************************************************************/
+BOOL make_creds_unix_sec(CREDS_UNIX_SEC *r_u,
+               uint32 uid, uint32 gid, uint32 num_grps, uint32 *grps)
+{
+       if (r_u == NULL) return False;
+
+       DEBUG(5,("make_creds_unix_sec\n"));
+
+       r_u->uid      = uid;
+       r_u->gid      = gid;
+       r_u->num_grps = num_grps;
+       r_u->grps     = grps;
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth)
+{
+       uint32 i;
+
+       if (r_u == NULL) return False;
+
+       prs_debug(ps, depth, desc, "creds_io_unix_sec");
+       depth++;
+
+       prs_align(ps);
+
+       prs_uint32("uid", ps, depth, &(r_u->uid));
+       prs_uint32("gid", ps, depth, &(r_u->gid));
+       prs_uint32("num_grps", ps, depth, &(r_u->num_grps));
+       if (r_u->num_grps != 0)
+       {
+               r_u->grps = (uint32*)Realloc(r_u->grps,
+                                      sizeof(r_u->grps[0]) *
+                                      r_u->num_grps);
+               if (r_u->grps == NULL)
+               {
+                       creds_free_unix_sec(r_u);
+                       return False;
+               }
+       }
+       for (i = 0; i < r_u->num_grps; i++)
+       {
+               prs_grow(ps);
+               prs_uint32("", ps, depth, &(r_u->grps[i]));
+       }
+       return True;
+}
+
+
+/*******************************************************************
+frees a structure.
+********************************************************************/
+void creds_free_unix_sec(CREDS_UNIX_SEC *r_u)
+{
+       if (r_u->grps != NULL)
+       {
+               free(r_u->grps);
+               r_u->grps = NULL;
+       }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL) return False;
+
+       prs_debug(ps, depth, desc, "creds_io_nt");
+       depth++;
+
+       prs_align(ps);
+
+       smb_io_dom_sid ("sid", &r_u->sid, ps, depth);
+       prs_align(ps);
+
+       sec_io_desc_buf("sd ", &r_u->sd , ps, depth);
+       prs_align(ps);
+
+       return True;
+}
+
+/*******************************************************************
+frees a structure.
+********************************************************************/
+void creds_free_nt_sec(CREDS_NT_SEC *r_u)
+{
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth)
+{
+       if (pwd == NULL) return False;
+
+       prs_debug(ps, depth, desc, "creds_io_pwd_info");
+       depth++;
+
+       prs_align(ps);
+
+       prs_uint32("nullpwd", ps, depth, &(pwd->null_pwd));
+       if (pwd->null_pwd)
+       {
+               return True;
+       }
+       
+       prs_uint32("cleartext", ps, depth, &(pwd->cleartext));
+       if (pwd->cleartext)
+       {
+               prs_string("password", ps, depth,   pwd->password, strlen(pwd->password), sizeof(pwd->password));
+               prs_align(ps);
+               return True;
+       }
+       prs_uint32("crypted", ps, depth, &(pwd->crypted));
+               
+       prs_uint8s(False, "smb_lm_pwd", ps, depth, (char*)&pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
+       prs_align(ps);
+       prs_uint8s(False, "smb_nt_pwd", ps, depth, (char*)&pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
+       prs_align(ps);
+
+       prs_uint8s(False, "smb_lm_owf", ps, depth, (char*)&pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
+       prs_align(ps);
+       prs_uint32("nt_owf_len", ps, depth, &(pwd->nt_owf_len));
+       if (pwd->nt_owf_len > sizeof(pwd->smb_nt_owf))
+       {
+               return False;
+       }
+       prs_uint8s(False, "smb_nt_owf", ps, depth, (char*)&pwd->smb_nt_owf, pwd->nt_owf_len);
+       prs_align(ps);
+
+       prs_uint8s(False, "lm_cli_chal", ps, depth, (char*)&pwd->lm_cli_chal, sizeof(pwd->lm_cli_chal));
+       prs_align(ps);
+       prs_uint32("nt_cli_chal_len", ps, depth, &(pwd->nt_cli_chal_len));
+
+       if (pwd->nt_cli_chal_len > sizeof(pwd->nt_cli_chal))
+       {
+               return False;
+       }
+       prs_uint8s(False, "nt_cli_chal", ps, depth, (char*)&pwd->nt_cli_chal, pwd->nt_cli_chal_len);
+       prs_align(ps);
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL) return False;
+
+       prs_debug(ps, depth, desc, "creds_io_nt");
+       depth++;
+
+       prs_align(ps);
+
+       /* lkclXXXX CHEAT!!!!!!!! */
+       prs_string("user_name", ps, depth,   r_u->user_name, strlen(r_u->user_name), sizeof(r_u->user_name));
+       prs_align(ps);
+       prs_string("domain", ps, depth,   r_u->domain, strlen(r_u->domain), sizeof(r_u->domain));
+       prs_align(ps);
+
+       creds_io_pwd_info("pwd", &r_u->pwd, ps, depth);
+       prs_align(ps);
+
+       prs_uint32("ntlmssp", ps, depth, &(r_u->ntlmssp_flags));
+
+       return True;
+}
+
+/*******************************************************************
+frees a structure.
+********************************************************************/
+void creds_free_nt(CREDS_NT *r_u)
+{
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL) return False;
+
+       prs_debug(ps, depth, desc, "creds_io_hybrid");
+       depth++;
+
+       prs_align(ps);
+
+       prs_uint32("reuse", ps, depth, &(r_u->reuse));
+       prs_uint32("ptr_ntc", ps, depth, &(r_u->ptr_ntc));
+       prs_uint32("ptr_uxc", ps, depth, &(r_u->ptr_uxc));
+       if (r_u->ptr_ntc != 0)
+       {
+               if (!creds_io_nt  ("ntc", &r_u->ntc, ps, depth)) return False;
+       }
+       if (r_u->ptr_uxc != 0)
+       {
+               if (!creds_io_unix("uxc", &r_u->uxc, ps, depth)) return False;
+       }
+       if (r_u->ptr_nts != 0)
+       {
+               if (!creds_io_nt_sec  ("nts", &r_u->nts, ps, depth)) return False;
+       }
+       if (r_u->ptr_uxs != 0)
+       {
+               if (!creds_io_unix_sec("uxs", &r_u->uxs, ps, depth)) return False;
+       }
+       return True;
+}
+
+void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from)
+{
+       if (from == NULL)
+       {
+               to->user_name[0] = 0;
+               return;
+       }
+       fstrcpy(to->user_name, from->user_name);
+};
+
+void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from)
+{
+       if (from == NULL)
+       {
+               ZERO_STRUCTP(to);
+               return;
+       }
+       memcpy(&to, &from, sizeof(*from));
+};
+
+void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from)
+{
+       if (from == NULL)
+       {
+               to->uid = -1;
+               to->gid = -1;
+               to->num_grps = 0;
+               to->grps = NULL;
+               return;
+       }
+       to->uid = from->uid;
+       to->gid = from->gid;
+       to->num_grps = 0;
+       to->grps = NULL;
+
+       if (from->num_grps != 0)
+       {
+               size_t size = to->num_grps * sizeof(to->grps[0]);
+               to->grps = (uint32*)malloc(size);
+               if (to->grps == NULL)
+               {
+                       return;
+               }
+               to->num_grps = from->num_grps;
+               memcpy(to->grps, from->grps, size);
+       }
+};
+
+void copy_nt_creds(struct ntuser_creds *to,
+                               const struct ntuser_creds *from)
+{
+       if (from == NULL)
+       {
+               to->domain[0] = 0;
+               to->user_name[0] = 0;
+               pwd_set_nullpwd(&to->pwd);
+               to->ntlmssp_flags = 0;
+
+               return;
+       }
+       safe_strcpy(to->domain   , from->domain   , sizeof(from->domain   )-1);
+       safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1);
+       memcpy(&to->pwd, &from->pwd, sizeof(from->pwd));
+       to->ntlmssp_flags = from->ntlmssp_flags;
+};
+
+void copy_user_creds(struct user_creds *to,
+                               const struct user_creds *from)
+{
+       ZERO_STRUCTP(to);
+       if (from == NULL)
+       {
+               to->ptr_ntc = 0;
+               to->ptr_uxc = 0;
+               to->ptr_nts = 0;
+               to->ptr_uxs = 0;
+               copy_nt_creds(&to->ntc, NULL);
+               copy_unix_creds(&to->uxc, NULL);
+               copy_nt_sec_creds(&to->nts, NULL);
+               copy_unix_sec_creds(&to->uxs, NULL);
+               to->reuse = False;
+               return;
+       }
+       to->ptr_nts = from->ptr_nts;
+       to->ptr_uxs = from->ptr_uxs;
+       to->ptr_ntc = from->ptr_ntc;
+       to->ptr_uxc = from->ptr_uxc;
+       if (to->ptr_ntc != 0)
+       {
+               copy_nt_creds(&to->ntc, &from->ntc);
+       }
+       if (to->ptr_uxc != 0)
+       {
+               copy_unix_creds(&to->uxc, &from->uxc);
+       }
+       if (to->ptr_ntc != 0)
+       {
+               copy_nt_sec_creds(&to->nts, &from->nts);
+       }
+       if (to->ptr_uxc != 0)
+       {
+               copy_unix_sec_creds(&to->uxs, &from->uxs);
+       }
+       to->reuse = from->reuse;
+};
+
+void free_user_creds(struct user_creds *creds)
+{
+       creds_free_unix(&creds->uxc);
+       creds_free_nt  (&creds->ntc);
+       creds_free_unix_sec(&creds->uxs);
+       creds_free_nt_sec  (&creds->nts);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL) return False;
+
+       prs_debug(ps, depth, desc, "creds_io_cmd");
+       depth++;
+
+       prs_align(ps);
+
+       prs_uint16("version", ps, depth, &(r_u->version));
+       prs_uint16("command", ps, depth, &(r_u->command));
+
+       prs_string("name   ", ps, depth,   r_u->name, strlen(r_u->name), sizeof(r_u->name));
+       prs_align(ps);
+       
+       prs_uint32("ptr_creds", ps, depth, &(r_u->ptr_creds));
+       if (r_u->ptr_creds != 0)
+       {
+               if (!creds_io_hybrid("creds", r_u->cred, ps, depth))
+               {
+                       return False;
+               }
+       }
+
+
+       return True;
+}
+
+
+BOOL create_ntuser_creds( prs_struct *ps,
+                               const char* name, 
+                               uint16 version, uint16 command,
+                               const struct ntuser_creds *ntu,
+                               BOOL reuse)
+{
+       CREDS_CMD cmd;
+       struct user_creds usr;
+
+       ZERO_STRUCT(cmd);
+       ZERO_STRUCT(usr);
+
+       DEBUG(10,("create_user_creds: %s %d %d\n",
+               name, version, command));
+
+       usr.reuse = reuse;
+
+       fstrcpy(cmd.name, name);
+       cmd.version = version;
+       cmd.command = command;
+       cmd.ptr_creds = ntu != NULL ? 1 : 0;
+       cmd.cred = &usr;
+
+       if (ntu != NULL)
+       {
+               copy_nt_creds(&usr.ntc, ntu);
+               usr.ptr_ntc = 1;
+       }
+       else
+       {
+               usr.ptr_ntc = 0;
+       }
+               
+       prs_init(ps, 1024, 4, 0, False);
+
+       ps->offset = 4;
+       return creds_io_cmd("creds", &cmd, ps, 0);
+}
+
+BOOL create_user_creds( prs_struct *ps,
+                               const char* name, 
+                               uint16 version, uint16 command,
+                               const struct user_creds *usr)
+{
+       CREDS_CMD cmd;
+
+       ZERO_STRUCT(cmd);
+
+       DEBUG(10,("create_user_creds: %s %d %d\n",
+               name, version, command));
+
+       fstrcpy(cmd.name, name);
+       cmd.version = version;
+       cmd.command = command;
+       cmd.ptr_creds = usr != NULL ? 1 : 0;
+       cmd.cred = usr;
+
+       prs_init(ps, 1024, 4, 0, False);
+
+       ps->offset = 4;
+       return creds_io_cmd("creds", &cmd, ps, 0);
+}